在较大的字符串中查找较小的字符串

时间:2015-05-16 02:17:48

标签: c++

说明是:您的程序从用户接收两个符号串:第一个长符号然后是短符号。然后你的程序返回长字符串中的所有位置,其中短字符串作为子字符串出现。 例如:长字符串是" aabcccbabc"而简短的是" abc"。短字符串可以在长字符串中看到两次" aabcccbabc"位置1和7(字符串中位置的枚举始终从0开始)。子串的位置是整个字符串中第一个符号的位置。您不能使用任何内置工具,如strlen()。  我无法输出出现次数和位置数。请帮忙!我觉得我已经尝试了一切!

#include <iostream>
using namespace std;

int main()
{
int NUM_MTCH, POSS1, POSS2, LENS1, LENS2 ;
NUM_MTCH=0;    //NUM_MTCH= THE NUMBER OF MATCHES
POSS1=0;       //POSITION OF PATTERM IN STRING2
POSS2=0;       //POSITION OF PATTERN IN STRING1
LENS1=0;       //LENGTH OF FIRST STRING
LENS2=0;       //LENGTH OF SECOND STRING
bool SUCCESS(true);
string S1, S2;
do
{
    cout<< "Enter First String: ";
    cin>> S1;
    for (POSS1=0; S1[POSS1] != '\0'; POSS1++)
    {
        LENS1++;
    }
    cout<< "Enter Second String: ";
    cin>>S2;
    for (POSS2=0; S2[POSS2] != '\0'; POSS2++)
    {
        LENS2++;
    }

}
while(LENS2>LENS1);

while (S1[POSS1] != '\0')
{
for(POSS1=0; S1[POSS2+POSS1]==S2[POSS2]; POSS2++)
{
    if (S1[POSS1+POSS2] == S2[POSS2])
    {
        SUCCESS==true;
    }
}
}

while (S1[POSS1]!= '\0')
{
if (S1[LENS2]==S2[POSS2])
{
    NUM_MTCH++;
    if(NUM_MTCH != 0)
    {
        cout<<"POSITIONS: "<<POSS1;
        cout<<"NUMBER OF OCCURENCES: "<<NUM_MTCH;
    }
}
}
POSS1++; 
if (NUM_MTCH==0)
{
cout<<"NOTHING";
}

return 0;
}

3 个答案:

答案 0 :(得分:1)

您可以使用std::string::find()轻松解决此问题。 find()将在字符串中搜索所提供字符串的第一个匹配项,并指向它在其中找到的位置。如果未找到任何内容,则返回std::string::npos。您可以继续从找到的最后一个位置调用find(),直到找不到更多的子字符串

std::string mainString = "aabcccbabc";
std::string subString = "abc";

std::vector<size_t> positions;
std::size_t index = 0;

// find sub-string and add positrion to vector.  If no string found end the loop
while((index = mainString.find(subString, index)) != std::string::npos)
{
    positions.push_back(index);
    ++index;  // increment index to search for next string
}

for (auto e : positions)
    std::cout << e << std::endl;

这是

的输出
1
7

修改

由于你有一个糟糕的教练并且你不允许使用实际的C ++,你可以使用以下函数来查找子字符串是否存在:

bool stringcmp(const char* sub, const char* main)
{
    while(*sub && (*sub==*main))
        sub++,main++;
    return *sub == '\0'; // if we didn't reach the end of sub then its false
}

您的主程序如下:

char* mainString = "aabcccbabc";
char* subString = "abc";
char* crwaler = mainString;

int positions[100];  // assuming there wont be more than 100 occurrences You might want to do something different
int index = 0;
int occurrences = 0;

// go untill the end of the string
while(*crwaler != '\0')
{
    if (stringcmp(subString, crwaler) == true)
    {
        positions[occurrences] = crwaler - mainString;
        occurrences++;
    }
    crwaler++;
}

for (int i = 0; i < occurrences; i++)
    std::cout <<positions[i] << std::endl;

答案 1 :(得分:0)

此代码存在很大问题。

  1. std::string不会在\0
  2. 中终止
  3. 您在所有CAPS中的格式很难理解
  4. 你有遍布各处的循环
  5. 基本的O(n * m)算法(n是字符串1的长度,m是字符串2的长度),如下所示:

    • 对于字符串1中的每个字符(长字符串)
      • 查看此字符是否从字符串1开始匹配字符串2(短字符串)
      • 的子字符串

    一些简短的代码:

    size_t matches = 0;
    std::string s1 = "aabcccbabc";
    std::string s2 = "abc";
    for(size_t i=0; i < (s1.size()-s2.size()+1); ++i)
    {
        if(s1.substr(i,s2.size()) == s2)
        {
            std::cout << "Found match at index " << i << " in 1st string\n";
            ++matches;
        }
    }
    
    std::cout << "Found " << matches << " match(es)" << std::endl;
    

    输出:

      

    在第一个字符串中的索引1处找到匹配   在第1个字符串中的索引7处找到匹配   找到2个匹配项目

    就“内置工具”而言,您已经在使用std::string,因此我仅限于使用substr这样的基本功能来获取子字符串和{{1}为了获得长度。

    当然,您可以使用其他功能更轻松地完成此操作(请参阅NathanOliver的answer),size()或Boost

    修改

    您可以将<algorithm>的检查替换为另一个循环。就是这样:

    substr

    变为:

    if(s1.substr(i,s2.size()) == s2)
    {
        std::cout << "Found match at index " << i << " in 1st string\n";
        ++matches;
    }
    

答案 2 :(得分:0)

好吧,我刚刚对你的代码进行了一些更改,现在它运行正常,因为你不想使用内置函数作为std :: string :: size()或std :: string :: substr ()

但首先请记住:  1- a std :: string不是NUL终止的,所以如上所述,你对0的检查不会起作用。  2-正如@andyG所说,你在所有CAPS中的格式很难理解。

这是代码

    #include <iostream>  
    #include<string>
    using namespace std;

    int main()
    {
      int NUM_MTCH, POSS1, POSS2, LENS1, LENS2;
      NUM_MTCH = 0;    //NUM_MTCH= THE NUMBER OF MATCHES
      POSS1 = 0;       //POSITION OF PATTERM IN STRING2
      POSS2 = 0;       //POSITION OF PATTERN IN STRING1
      LENS1 = 0;       //LENGTH OF FIRST STRING
      LENS2 = 0;       //LENGTH OF SECOND STRING
      bool SUCCESS(false);
      string S1, S2;

      cout << "Enter First String: ";
      cin >> S1;
      S1 += "\0"; 
      for (POSS1 = 0; S1[POSS1] != '\0'; POSS1++)
      {
         LENS1++;
      }

      cout << "Enter Second String: ";
      cin >> S2;
      S2 += "\0";
      for (POSS2 = 0; S2[POSS2] != '\0'; POSS2++)
      {
        LENS2++;
      }


      for (POSS1 = 0; POSS1 < (LENS1 - LENS2 + 1); POSS1++)
      {
          if (S1[POSS1] == S2[0])
          {
             POSS1++;
             for (int j = 1; j < LENS2; j++){
                if (S1[POSS1] == S2[j]){
                   SUCCESS = true;
                   POSS1++;
                }
                else{
                   SUCCESS = false;
                } 
            }
            if (SUCCESS){
                cout << "at position" << POSS1 - LENS2 << endl;
                NUM_MTCH++;
            }
            POSS1--;

        }
    }



if (NUM_MTCH == 0)
{
    cout << "NOTHING";
}
else{
    cout <<"number of matches: "<< NUM_MTCH << endl;
}



return 0;

}