Thread: Equidistant Letter Sequencing

  1. #16
    Registered User
    Join Date
    Jan 2005
    Posts
    7,364
    >> I replaced SUBSTRINGLIST[SUBSTRING].clear() with just SUBSTRINGLIST.clear()
    The first was correct in your code. You only want to clear the current substring.

    >> i <= TEXT.size();
    You should be using < instead of <=. You did this in the other loop also.

    >> if(SEARCHWORD[SUBSTRING] == TEXT[i])
    This appears to be where your code differs from my algorithm. You might be confused because you are using SUBSTRING as the index into SUBSTRINGLIST, where I was using SUBSTRING as the actual substring at SUBSTRINGLIST[j].

    Also, the else is under the wrong if in the code.

    Finally, I realized there is an important part missing. I added it in an edit.
    Last edited by Daved; 04-19-2006 at 12:39 PM.

  2. #17
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Yes thats much clearer. I'll adjust my code appropriatley. I see now why the original would not have worked.

    Thanks.

  3. #18
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Here is the adjusted code:

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        string TEXT = "";
        string SEARCHWORD = "";
        int SKIP = 0;
        
        cout<<"Input text to search: "<<endl;
        cin>>TEXT;
        cout<<endl;
        
        cout<<"Input word to search for: "<<endl;
        cin>>SEARCHWORD;
        cout<<endl;
        
        cout<<"Input skip value: "<<endl;
        cin>>SKIP;
        cout<<endl;
        
        vector<string> SUBSTRINGLIST(SKIP);
        
        for(int i = 0; i < TEXT.size(); i++)
        {
            for(int j = 0; j < SUBSTRINGLIST.size(); j++)
            {
                if((i % SKIP == j) && (SEARCHWORD[SUBSTRINGLIST[j].size()] == TEXT[i]))
                {
                    SUBSTRINGLIST[j].push_back(TEXT[i]);
                    if(SUBSTRINGLIST[j].size() == SEARCHWORD.size())
                    {
                         cout<<"Search word found."<<endl;
                    }
    
                }
                else 
                {
                     SUBSTRINGLIST[j].clear();
                }
    
            }
        }
        
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    It no works if I put in something like: gjhjkthellodfds and ask it to search for hello with a skip of one. But it still doesn't pick NEW in UNDERWARANTY with a skip of two.

    Is there something else I am missing?

    Thanks.

  4. #19
    Registered User
    Join Date
    Jan 2005
    Posts
    7,364
    Oops... sorry.. in my version the ((i % SKIP == j) was a separate step that continued if they weren't equal. Now, if they're not equal it will clear the substring, which is not what you want.

    I edited again. Feel free to try and debug these and other errors yourself. Remember that the algorithm still has the lllama error and you'll have to figure that out.
    Last edited by Daved; 04-19-2006 at 01:20 PM.

  5. #20
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Yes, I just thought about the lllama error, and I am working on it.

    I also changed my output statement to tell me the position of the first letter of the word found:

    Code:
    coutcout<<endl<<"Search word found at:"<<((i + 1) - (SEARCHWORD.size() + SKIP - 1))<<endl;
    Ill work in the correction.

    Thanks.
    Last edited by Tachyon; 04-19-2006 at 02:06 PM.

  6. #21
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Ok here is the corrected code thus far:

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        string TEXT = "";
        string SEARCHWORD = "";
        int SKIP = 0;
        int j = 0;
        
        cout<<"Input text to search: "<<endl;
        cin>>TEXT;
        cout<<endl;
        
        cout<<"Input word to search for: "<<endl;
        cin>>SEARCHWORD;
        cout<<endl;
        
        cout<<"Input skip value: "<<endl;
        cin>>SKIP;
        cout<<endl;
        
        vector<string> SUBSTRINGLIST(SKIP);
        
        for(int i = 0; i < TEXT.size(); i++)
        {
            j = i % SKIP;
            if(SEARCHWORD[SUBSTRINGLIST[j].size()] == TEXT[i])
            {
                 SUBSTRINGLIST[j].push_back(TEXT[i]);
                          
                 if(SUBSTRINGLIST[j].size() == SEARCHWORD.size())
                 {
                      cout<<endl<<"Search word found at:"<<((i + 1) - (SEARCHWORD.size() + SKIP - 1))<<endl;
                 }
            }
            else 
            {
                 SUBSTRINGLIST[j].clear();
            }
    
        }
        
        system("PAUSE");
        return EXIT_SUCCESS;
    I am elated to say that it works.

    Here is a sample of the output:

    Input text to search: UNDERWARANTY

    Input word to search for: NEW

    Input skip value: 2

    Search word found at: 2

    Now to work on the lllama error

    Thanks.

  7. #22
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    So far I have found this that solves the lllama error:

    Code:
            if(SEARCHWORD[SUBSTRINGLIST[j].size()] == TEXT[i] || SEARCHWORD[SUBSTRINGLIST[j].size()] == TEXT[i + 1])
            {
                 SUBSTRINGLIST[j].push_back(TEXT[i]);
                          
                 if(SUBSTRINGLIST[j].size() == SEARCHWORD.size())
                 {
                      cout<<endl<<"Search word found at: "<<((i + 1) - (SEARCHWORD.size() + SKIP - 1))<<endl;
                 }
            }
            else 
            {
                 SUBSTRINGLIST[j].clear();
            }
    although it throws off the the formula to calculate the position of the Search Word by 1 and I think it may find it more then once in some instances. I am not quite sure about the cause of these errors, but I am looking into it.

    Thanks.

  8. #23
    Super Moderater.
    Join Date
    Jan 2005
    Posts
    374
    An important consideration if you wish to stay faithful to the ELS principal is...

    'If you take your block of text to be a two dimensional array, then you have to imagine the two vertical edges of the array as pasted together, with the end of the second to the beginning of the third and so on. So you get a cylinder on which the test spirals down in one long line.'


    Another important consideration is measuring the promixty of two words found by ELS, to determine their significance rating.

  9. #24
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Quote Originally Posted by treenef
    An important consideration if you wish to stay faithful to the ELS principal is...

    'If you take your block of text to be a two dimensional array, then you have to imagine the two vertical edges of the array as pasted together, with the end of the second to the beginning of the third and so on. So you get a cylinder on which the test spirals down in one long line.'


    Another important consideration is measuring the promixty of two words found by ELS, to determine their significance rating.
    Yes, and I only found one program to do ELS on ASCII and it did not have a feature to analyse words that occured on the same skip and their proximity. I am making mine with this feature and and a couple of others.

    I haven't found a pat solution to the lllama error yet. Can anyone see a way to fix it? My previous solution works to an extent, but it introduces new errors that I mentioned.

    Also, in order to display the grid should I simply use a loop to write out the text's substrings or is there a better way?

    Thanks.

  10. #25
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    I inserted this code to write the matrixes if a word is found:

    Code:
    for(int c = 0; c <= TEXT.size(); c++)
    {
             cout<<TEXT[c];
             ++s;
             if(s == SKIP)
             {
                    cout<<endl;
                    s = 0;
              }
    }
    Thanks.

  11. #26
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    I have greatly modified this code and I am now using some different methods.

    My code now looks like this (a little messy, but I'll fix that in a bit):

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    #include "Console.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        string TEXT = "";
        string SEARCHWORD = "";
        int SKIP = 0;
        int j = 0;
        int g = 0;
        int i = 0;
        int printgrid = 0;
        int count = 0;
        namespace con = JadedHoboConsole;
        
        cout<<con::fg_white;
        cout<<"Input text to search: ";
        cin>>TEXT;
        cout<<endl;
        
        cout<<"Input word to search for: ";
        cin>>SEARCHWORD;
        cout<<endl;
        
        cout<<"Input skip value: ";
        cin>>SKIP;
        cout<<endl;
        
        int RL = ((TEXT.length()) / SKIP);
        string ROWS[RL];
        string COLUMNS[SKIP];
        const char* text = TEXT.c_str();
    
        int SEARCHWORDPOSITIONS[5000];
        int INSTANCE[SKIP];
    
        while(g < 5000)
        {SEARCHWORDPOSITIONS[g] = 0;
         g++;}
        while(j < SKIP)     
        {INSTANCE[j] = 0;
         j++;}
    
        g = 0;
        j = 0;
        
        // output the length of the text, rows, and columns
        cout<<"Text length: "<<TEXT.length()<<" Rows: "<<RL<<" Columns: "<<SKIP<<endl<<endl;
        
        // split the the text into rows
        while((j < RL) && (g <= (TEXT.length() - SKIP)))
        {
             ROWS[j] = TEXT.substr(g,SKIP);
             g = g + SKIP;
             j++;
        }
    
        // split the text into columns
        for(g = 0; g < RL; g++)
        {    
             for(j = 0; j < SKIP; j++)
             {
                  COLUMNS[j].append(ROWS[g].substr(j,1));
             }
        }
    
        // find all instances of the search word
        g = 0;
        i = 0;
        j = 0;
        for(g = 0; g < SKIP; g++)
        {
    	      while((COLUMNS[g].find(SEARCHWORD,i)) != string::npos)
              {
                    if(COLUMNS[g].find(SEARCHWORD,i) == 0)
                    {
                          SEARCHWORDPOSITIONS[j] = 1 * (g + 1);
                    }
                    else
                    {
                          SEARCHWORDPOSITIONS[j] = ((COLUMNS[g].find(SEARCHWORD,i)) * (g + 1));
                    }
    		        
                    i += (SEARCHWORD.length() + 1);
    		        (INSTANCE[g])++;
    		        ++count;
    		        j++;
              }
        }
        cout<<endl;
    
        j = 1;
        for(g = 0; g < SKIP; g++)
        {
              if(count != 0)
              {
                            printgrid = 1;
    		        if(g == 0){cout<<SEARCHWORD<<" was found at: ";}
    		        while(j <= count)
                            {
                                      cout<<SEARCHWORDPOSITIONS[g]<<" ";
                                      j++;
                            }
              }
              else
              {
                            cout<<SEARCHWORD<<" was not found."<<endl;
              }
        }
        cout<<endl<<endl;
        
        i = 0;
        j = 0;
        if(printgrid == 1)
        {	
    
        	 // print the grid to the screen
             for(int g = 0; g < TEXT.length(); g++)
        	 {
                     j = 0;
                     i = 0;
    		         if(((g + 1) % SKIP) != 0)
    		         {
    			           while(j < count && i == 0)
    			           {
                                                for(int c = 0; c < SEARCHWORD.length(); c++)
                                               {
                                                         if((SEARCHWORDPOSITIONS[j] + (c * SKIP)) == (g + 1))
                                                         {i = 1;}
                                                }
                                       j++;
                                       }
    
    			           if(i == 0)
    			           {
                    		            cout<<TEXT[g];
                                       }
    			           else
    			           {
    				                               cout<<con::fg_red<<con::bg_white<<TEXT[g]<<con::fg_white<<con::bg_black;
                                       }
                           }
    		       else
    		       {
    			           while(j < count && i == 0)
                                       {
                                                 for(int c = 0; c < SEARCHWORD.length(); c++)
                                                {
                                                          if((SEARCHWORDPOSITIONS[j] + (c * SKIP)) == (g + 1))
                                                          {i = 1;}
                                                }
    				             j++;
                                       }
    
    			           if(i == 0)
    			           {
                    		             cout<<TEXT[g]<<endl;
    		                   }
    			           else
    			           {
    				               cout<<con::fg_red<<con::bg_white<<TEXT[g]<<con::fg_white<<con::bg_black<<endl;
                                       }
                            }
                 }
        }
        cout<<endl;
           
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    I would like to next have it read in the TEXT from a file instead of user input. That way I can search large portions of text without having to retype it.

    I would also like to output the grid to a text file in order to easily view it. I would also like to be able to output the found words in a highlighted format like my code does now.

    I am familiar with file input and output, but it has been forever since I have used them. Also, I am concerned with making the output grid formatted correctly.

    Any suggestions on how to go about this next step?

    Thanks.
    Last edited by Tachyon; 04-21-2006 at 01:04 PM.

  12. #27
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,616
    The fstream library handles file I/O in part by inheriting all the methods of ostream and istream to work with files.

    I cannot lay enough stress on the importance of understanding the nuts and bolts of all formats of I/O, and remembering them. There are tutorials on the Cprogramming.com site and elsewhere.

    Also, I am sure that iomanip can help you format the grids in the text files.
    Last edited by whiteflags; 04-21-2006 at 01:27 PM.

  13. #28
    Registered User
    Join Date
    Apr 2006
    Posts
    28
    Quote Originally Posted by citizen
    The fstream library handles file I/O in part by inheriting all the methods of ostream and istream to work with files.

    I cannot lay enough stress on the importance of understanding the nuts and bolts of all formats of I/O, and remembering them. There are tutorials on the Cprogramming.com site and elsewhere.

    Also, I am sure that iomanip can help you format the grids in the text files.
    I have read through the tutorial to refresh my memory on files. I am trying to get the file name as input from the user.

    It doesn't want to except a string, char, or char array or a pointer for any of the preceding. I can't figure out how to get it to except variable input for the filename.

    How do I go about that?

    Thanks.

  14. #29
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Did you see this tutorial? http://www.cprogramming.com/tutorial/lesson10.html

    You can just read the filename in like normal with cin.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  15. #30
    Registered User
    Join Date
    Jan 2005
    Posts
    7,364
    If you use a string to read in the filename, you must use .c_str() to pass a const char* to the ifstream constructor or open function.

    Your input code should be separated into a function that takes an istream& as a parameter. That way you can pass cin if you want to read from cin, or pass an ifstream variable if you want to read from a file.

    Similarly, you should separate the rest of the code into logically distinct functions to make expansion and enhancement easier.

    Finally, I used ALL CAPS to make my pseudo-code clearer, but in actual code normally identifiers with all caps are reserved for constants and preprocessor symbols. I would go ahead and move to normal variable naming as you continue with this project.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do I ...
    By geekrockergal in forum C Programming
    Replies: 21
    Last Post: 02-07-2009, 10:40 AM
  2. counting letter occurences in a string
    By pjr5043 in forum C++ Programming
    Replies: 35
    Last Post: 05-05-2008, 09:18 PM
  3. Advice requested, Code makes sense to me, not compiler
    By andrew.bolster in forum C Programming
    Replies: 53
    Last Post: 01-06-2008, 01:44 PM
  4. help using strings and mapping
    By trprince in forum C Programming
    Replies: 29
    Last Post: 12-01-2007, 04:01 PM
  5. Big Letter became small letter
    By cogeek in forum C Programming
    Replies: 27
    Last Post: 12-13-2004, 02:04 PM