Question

I'm taking a users input like so:

algo_type "pattern" filename 

ex.

bf "inging" input_file.txt

As of now I separate the users input into three different variables, one for the algo_type, one for the pattern I'm looking for, and one for the filename. Once I get the pattern and filename I'm trying to take the pattern into the Bruteforce algo and search each line and print the position that pattern occurs in the line of the .txt file. Right now though every time I enter the input into the algo it returns -1 meaning the BruteForce isn't running? What exactly am I doing wrong here?

int BruteForce(const string& line, const string& pattern){
    int n , m;
    n = line.length();
    m = pattern.length();

    for(int  i = 0 ; i < n - m ; i++){

            int j = 0;

            while( j < m  && line[i + j] == pattern[j]){
            j = j+1;

            if( j == m){
                    return i;

                    }
            }        
    }
    return -1; 
 }

  int main(){

    string text, algo_type , pattern , fname, line;
    getline(cin ,text);
    istringstream  iss(text);

    if(iss >>  algo_type  >>  pattern  >> fname){
            cout <<  algo_type  <<  pattern << fname << "'\n'";
    }

    int i = 0;
    ifstream ifs;
    ifs.open(fname.c_str());
    while(getline(ifs, line) && fname != ""){
            if( algo_type == "bf"){
                    cout << "Line " << i++ << ":" << BruteForce(line,pattern) << endl;

            }
    }
    return 0;
  } 
Was it helpful?

Solution

I suppose you wanted return -1 at the end of BruteForce, rather then at the end of the first iteration.

Also, the first loop condition needs to have <= instead of <, or matches ending in the very position won't be found.

Here's a complete, fixed version: EDIT as per the edit, list multiple matches within lines:

#include <string>

using namespace std;

int BruteForce(const string& line, size_t start, const string& pattern) {
    const size_t n = line.length();
    const size_t m = pattern.length();

    if (n<m) return -1;

    for(size_t i = start; i <= (n - m); i++) {
        for(size_t j=0; j < m  && (line[i + j] == pattern[j]); ++j) {
            if(j == m-1) {
                return i;
            }
        }
    }
    return -1;
}

#include <iostream>
#include <fstream>
#include <sstream>

int main() {
    string text, algo_type, pattern, fname, line;
    getline(cin ,text);
    istringstream iss(text);
    if(iss >>  algo_type  >>  pattern  >> fname) {
        cout << " " << algo_type  << " " << pattern <<  " " <<fname << "\n";
    }

    int i = 1;
    ifstream ifs;
    ifs.open(fname.c_str());
    while(getline(ifs, line) && fname != "") {
        if(algo_type == "bf") {
            int pos = -1;

            while (-1 != (pos = BruteForce(line, pos+1, pattern)))
                cout << "Line " << i << ":" << pos << " " << line << endl;
        }
        i++;
    }
    return 0;
}

See it Live on Coliru: http://coliru.stacked-crooked.com/a/f1a7693d7d3bd7c5

I've tested it with

./test <<< "bf iss /etc/dictionaries-common/words" | grep Miss

Which printed

Line 10241:1 Miss
Line 10242:1 Mississauga
Line 10242:4 Mississauga
Line 10243:1 Mississippi
Line 10243:4 Mississippi
Line 10244:1 Mississippi's
Line 10244:4 Mississippi's
Line 10245:1 Mississippian
Line 10245:4 Mississippian
Line 10246:1 Mississippian's
Line 10246:4 Mississippian's
Line 10247:1 Mississippians
Line 10247:4 Mississippians
Line 10248:1 Missouri
Line 10249:1 Missouri's
Line 10250:1 Missourian
Line 10251:1 Missourian's
Line 10252:1 Missourians
Line 10253:1 Missy
Line 10254:1 Missy's
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top