使用向量来解决C ++中的字谜

时间:2014-08-26 02:14:24

标签: c++ vector

我有一个函数,它接受两个字符串向量,并比较每个元素,看它们是否是彼此的字谜。

向量#1:“bat”,“add”,“zyz”,“aaa”

向量#2:“标签”,“爸爸”,“xyx”,“bbb”

限制和其他澄清的内容:该函数应该遍历两个向量并比较字符串。我只应该根据每个向量的索引进行比较;意思是我只比较第一个索引中的字符串,然后比较第二个索引中的字符串,依此类推。可以安全地假设作为参数传入的向量将始终具有相同的大小。

如果比较的字符串是字谜,则在屏幕上打印“匹配”。如果不是,则打印“不匹配”。

输出:匹配匹配无匹配否匹配

我对这个问题的理解非常荒谬,我知道如何扭转字符串,但是当它达到这个目标时,我会变得有点无能为力。

我知道我需要迭代每个向量,然后进行比较。但是,我如何比较字符串中的每个字母?另外,我不允许包含其他任何内容,如算法,排序或集合。我试过挖掘很多问题,但大多数答案都是用这个。

如果有任何关于如何解决这个问题的提示,那就太棒了。我将很快发布我发现的内容。

这是我到目前为止所得到的:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

void anagrams(const vector<string>& vOne, const vector<string>& vTwo){
for(int i=0; i< vOne.size(); i++){
    for(int j=0; j< vTwo.size(); j++){
        if(vOne[i].size() != vTwo[j].size()){
            cout << 0 << endl;
        }
        else {
            cout << 1 << endl;
        }
    }
  }
}
void quicksort(vector<int>& a, int low, int high){
    if(low < high)
    {
        int mid = (low + high)/2;
        int pivot = a[mid];
        swap(a[high], a[mid]);

        int i, j;

        for(i=low, j=high-1; ;){
            while(a[i]<pivot) ++i;
            while(j>i && pivot < a[j]) --j;
            if (i < j)
                swap(a[i++], a[j--]);
            else
                break;
        }

        swap(a[i], a[high]);
    } 
    quicksort(a, low, i - 1);
    quicksort(a, i + 1, high);
}

提前致谢!

4 个答案:

答案 0 :(得分:2)

虽然您无法使用排序,但您仍应对要检查的单词进行排序,以查看它们是否为字谜。你只需要手动对char []进行排序,这是不幸的,但这是一个很好的练习。我会创建一个谓词,一个比较2个字符串并返回true或false的函数,并使用它来检查它们是否是字谜。此外,似乎您不需要打印出实际匹配的两个单词,如果这是真的,那么您可以在第一次读取它们时对向量中的单词进行排序,然后通过谓词运行它们功能

// Predicate
bool isMatch(const string &lhs, const string &rhs)
{
    ...sort and return lhs == rhs;
}

如果您编写函数,如上所述,您将通过const引用传递参数,然后您可以将参数复制(不使用strcpy()(由于漏洞)参数到char []并对单词进行排序。我建议把你的排序作为自己的功能。 另一个提示,请记住事情要快得多,并且stl使用智能ptrs进行排序。无论如何,我希望这有点帮助,我不想给你答案。

答案 1 :(得分:1)

只要字符串只包含a-z和A-Z之间的字符,这个解决方案就相当快了

bool is_anagram( const string& s1, const string& s2 ) {
    if( s1.size() != s2.size() ) {
        return false;
    }

    size_t count[ 26 * 2 ] = { 0 };

    for( size_t i = 0; i < s1.size(); i++ ) {
        char c1 = s1[ i ];
        char c2 = s2[ i ];

        if( c1 >= 'a' ) {
            count[ c1 - 'a' ]++;
        }
        else {
             count[ c1 - 'A' + 26 ]++;
        }

        if( c2 >= 'a' ) {
            count[ c2 - 'a' ]--;
        }
        else {
             count[ c2 - 'A' + 26 ]--;
        }
    }
    for( size_t i = 0; i < 26 * 2; i++ ) {
        if( count[ i ] != 0 ) {
            return false;
        }
    }
    return true;
}

答案 2 :(得分:0)

如果你愿意使用C ++ 11,这里有一些相当低效的代码,用于查看两个字符串是否为字谜。我会留给你循环查看单词列表。

#include <iostream>
#include <vector>

using namespace std;

int count_occurrences(string& word, char search) {
    int count = 0;
    for (char s : word) {
        if (s == search) {
            count++;
        }
    }
    return count;
}

bool compare_strings(string word1, string v2) {       
    if (word1.size() != v2.size())
    {
        return false;
    }    
    for (char s: word1) //In case v1 contains letters that are not in v2
    {
        if (count_occurrences(word1, s) != count_occurrences(v2, s))
        {
            return false;
        }
    }        

    return true;
}

int main() {
    string s1 = "bat";
    string s2 = "atb";

    bool result = compare_strings(s1, s2);

    if (result)
    {
        cout << "Match" << endl;
    }
    else
    {
        cout << "No match" << endl;
    }

}

这可以通过简单计算给定字母在字符串中出现的次数来实现。更好的方法是按字母顺序对字符串中的字符进行排序,然后比较排序的字符串以查看它们是否相等。我会留给你改进的。

祝福。

答案 3 :(得分:0)

另一种解决方案,因为我非常无聊:

#include <iostream>
#include <vector>
#include <string>

int equiv_class(char c) {
   if ((c>='A')&&(c<='Z')) return c-'A';
   if ((c>='a')&&(c<='z')) return c-'a';
   return 27;
}

bool is_anagram(const std::string& a, const std::string& b)
{
   if (a.size()!=b.size()) return false;
   int hist[26]={};
   int nz=0; // Non-zero histogram sum tally
   for (int i=0, e=a.size() ; i!=e ; ++i)
   {
      int aclass = equiv_class(a[i]);
      int bclass = equiv_class(b[i]);
      if (aclass<27) {
         switch (++hist[aclass]) {
         case 1: ++nz; break; // We were 0, now we're not--add
         case 0: --nz; break; // We were't, now we are--subtract
         // otherwise no change in nonzero count
         }
      }
      if (bclass<27) {
         switch (--hist[bclass]) {
         case -1: ++nz; break; // We were 0, now we're not--add
         case  0: --nz; break; // We weren't, now we are--subtract
         // otherwise no change in nonzero count
         }
      }
   }
   return 0==nz;
}

int main()
{
   std::vector<std::string> v1{"elvis","coagulate","intoxicate","a frontal lobotomy"};
   std::vector<std::string> v2{"lives","catalogue","excitation","bottlein frontofme"};
   for (int i=0, e=(v1.size()==v2.size()?v1.size():0); i!=e; ++i) {
      if (is_anagram(v1[i],v2[i])) {
         std::cout << " Match";
      } else {
         std::cout << " No Match";
      }
   }
}