简体   繁体   English

在给定的字符串集中找到一些公共字符?

[英]Find number of common characters among given sets of strings?

For a given number of test cases, we are given an integer n where n is the number of strings and we have to find a number of common elements (elements which are present in each one of the strings).and length of strings can be upto 200,and a character(lower case) can be there multiple times in string. 对于给定数量的测试用例,我们得到一个整数n其中n是字符串的数量),我们必须找到许多公共元素(每个字符串中都存在的元素)。字符串的长度可以是最多200个字符,字符串中可以多次出现一个小写字符。

For example (one test case, three strings in the test case): 例如(一个测试用例,测试用例中的三个字符串):

2
3
Weeb
Hello
Anime

4

llana
allon
mellon 
gallon

OUTPUT [ first test case ]= 1 (as we can see "e" is common in all strings). OUTPUT [第一个测试用例] = 1(我们可以看到“ e”在所有字符串中都是通用的)。

[ second test case ] = 2 (as we can se "l" && "n" are common in all strings). [第二个测试用例] = 2(正如我们可以看到的,“ l”和&“ n”在所有字符串中都是通用的)。

I have tried to make an array of strings and compare them but I could not get any answer. 我试图制作一个字符串数组并进行比较,但是我没有任何答案。 my code 我的代码

#include <iostream>
#include<string>
#include<cstdio>

using namespace std;

int main(){
    int t;
    cin>>t;
   while(t--){
       int n,i,j,k,count=0;    
       cin>>n;
       string a[1000];

       for(i=0;i<n;i++)
        cin>>a[i];
       for(i=0;i<n;i++){
        for(j=0;j<4;j++){
         for(int k=0;k<4;k++){

         if(a[i][j]==a[i+1][k])           
            a[i][j]=a[i+1][k];

         else            
           a[i][j]=NULL;

        }
    }

  }

  for(i=0;a[i]!='\0';i++)
       count++;

   }

   cout<< count << endl;
   return 0;

 }

how i focus it: the ABC has 26 letters. 我如何关注它:ABC有26个字母。 Create an array with 26 positions, take the first word(String) and analyze the letters one by one. 创建一个具有26个位置的数组,获取第一个单词(字符串)并一个一个地分析字母。 Add each letter sort from A to Z to the array position as a sum to his value 1, at the end, search the highest one. 将从A到Z的每个字母排序加到数组位置,作为其值1的总和,最后搜索最高的一个。

example: 例:

String = HA String = HAA 字符串= HA字符串= HAA

ABZ[7] = 2 ABZ[0] = 3 ABZ [7] = 2 ABZ [0] = 3

Result Pos 0 = 3 = A 结果位置0 = 3 = A

:) :)

I must admit that I didn't fully understand the solution presented in the self-answer of OP . 我必须承认,我不完全了解OP自我解答中提供的解决方案。 This encouraged me to present a different one. 这鼓励我提出一个不同的观点。

The general idea is to apply set operations to the individual strings. 总体思路是将设置操作应用于单个字符串。

All characters of first string are possible candidates to be common. 第一个字符串的所有字符都可能是相同的候选字符。 For each other string, if a character of first is not in other string then it is removed from first string. 对于其他字符串,如果first字符不在其他字符串中,则将其从第一个字符串中删除。 (ie a set intersection) Finally, the left characters in first string are that which are common with all other strings. (即设定的交集)最后,第一个字符串中的左字符是所有其他字符串所共有的字符。

To make set operations in C++, I could have stored each string in a std::set to perform std::set_intersection() afterwards. 为了在C ++中进行设置操作,我可以将每个字符串存储在std::set再执行std::set_intersection()

Instead, I applied std::sort() to the first string. 相反,我将std::sort()应用于第一个字符串。 The string might have duplicated characters. 该字符串可能包含重复的字符。 These are removed by a succeeding call of std::unique() . 通过后续调用std::unique()删除它们。

The other strings (2 nd , 3 rd , etc.) are sorted as well. 其他字符串( 第二第三等)也进行排序。 The call of std::unique() isn't necessary because the following intersection won't consider any duplicate in the second string as there will never be one in the first string. 不需要调用std::unique()因为以下交集不会考虑第二个字符串中的任何重复项,因为第一个字符串中将永远不会有一个重复项。

For the intersection, I recalled an older answer of mine (to SO: how to find the intersection of two std::set in C++? ). 对于交集,我想起了我的一个较早的答案(对于SO:如何在C ++中找到两个std :: set的交集? )。 I considered to use std::set_intersection() but IMHO it might not store the result into the range it's reading from. 我考虑使用std::set_intersection()但恕我直言,它可能不会将结果存储到要读取的范围内。 I also didn't want another string copy for each iteration and, hence, used an alternative implementation intersection() instead. 我也不希望每次迭代都使用另一个字符串副本,因此,我使用了一个替代实现intersection()

This is what I got: 这就是我得到的:

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

void intersection(std::string &first, const std::string &second)
{
  std::string::iterator iter1 = first.begin();
  for (std::string::const_iterator iter2 = second.begin();
    iter1 != first.end() && iter2 != second.end();) {
    if (*iter1 < *iter2) iter1 = first.erase(iter1);
    else {
      if (!(*iter2 < *iter1)) ++iter1;
      ++iter2;
    }
  }
  first.erase(iter1, first.end());
}

size_t check(const std::vector<std::string> &sample)
{
  // check trivial case (sample empty)
  if (sample.empty()) return 0;
  std::string first = sample[0];
  // sort string characters by their values  
  std::sort(first.begin(), first.end());
  // remove duplicates
  std::string::iterator end = std::unique(first.begin(), first.end());
  first.erase(end, first.end());
  // check the other strings agains first
  for (size_t i = 1, n = sample.size(); i < n; ++i) {
    std::string other = sample[i];
    std::sort(other.begin(), other.end());
    intersection(first, other);
  }
#if 1 // set 0 to disable diagnostics
  // diagnostics
  std::cout << '"' << first << "\" ";
#endif // 1
  return first.size();
}

int main()
{
  std::vector<std::string> samples[] = {
    { "Weeb", "Hello", "Anime" },
    { "llana", "allon", "mellon", "gallon" }
  };
  // check samples
  for (const std::vector<std::string> &sample : samples) {
    // print input
    std::cout << "check(";
    const char *sep = "";
    for (const std::string &word : sample) {
      std::cout << sep << '"' << word << '"';
      sep = ", ";
    }
    std::cout << "):\n";
    // print common characters
    std::cout << "  Common characters: " << check(sample) << '\n';
  }
  return 0;
}

Output: 输出:

check("Weeb", "Hello", "Anime"):
  Common characters: "e" 1
check("llana", "allon", "mellon", "gallon"):
  Common characters: "ln" 2

Live Demo on coliru 在coliru上进行现场演示

Notes: 笔记:

  1. The algorithm doesn't distinguish between letters and any other character. 该算法不区分字母和其他任何字符。 It would work for digits and special characters (and any other character) as well. 它也适用于数字和特殊字符(以及任何其他字符)。

  2. According to the previous fact, the algorithm does distinguish lowercase and uppercase letters. 根据先前的事实,该算法确实区分小写字母和大写字母。 I'm not sure whether or not OP intended this nor if OP is aware about this. 我不确定OP是否打算这样做,或者OP是否知道这一点。 I found it legal to make it this way if there is no explicit constraint concerning this. 如果没有明确的限制,我认为这样做是合法的。 (And, it takes off the burden of any concerns regarding encoding, internationalization, and such.) (并且,它减轻了有关编码,国际化等方面的任何负担。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM