C ++在字符串向量中查找字符串的频率

Posted

技术标签:

【中文标题】C ++在字符串向量中查找字符串的频率【英文标题】:C++ Find Frequency of a String in a Vector of Strings 【发布时间】:2020-11-18 23:25:20 【问题描述】:

我目前正在开发一个小程序,它将确定 5 个字符串的向量是否包含满屋。在我的程序中,满屋子有一对牌和 3 个。

例如:["A", "A", "A", "K", "K"] 会是满堂彩,而["10", "J", "10", "10", "10"] 不会是满堂彩。

我已经编写了我的主要功能,以便用户可以使用以下代码将卡片值读入向量:

int main()

    vector<string> hand;
    string input;

    for (int i = 0; i < 5; i++)
    
        cout << "Card " << i + 1 << ": ";
        cin >> input;

        hand.push_back(input);
    

我想写一个 bool 函数,它以向量作为参数,如果向量包含满屋,则返回 true,否则返回 false。我的问题是我不确定在函数中循环遍历向量并找到每个字符串的频率以确定向量是否满座的有效方法。

例如,我希望我的函数有点像下面的:

bool isFullHouse(vector<string> hand)

     // loop through vector
     // record instance of string in vector
     // determine if the string has appeared either 2 times or 3 times in the vector

     // if it contains a full house
     return true

     // else
     return false

有没有人有一个体面的方法来完成这项任务?

【问题讨论】:

注意:在卡片代码中使用T代表10是一个常见的约定,这样所有的卡片都是一个字符,当与西装搭配时就像2STC,非常可预测并且易于使用。 提示:对数组进行排序。如果前两个和后三个匹配,或者前三个和后两个匹配,则检测到满堂。 我会按照上面提到的排序,但您也可以使用map&lt;string, int&gt; 来计算卡片,然后检查正确的组合。 我支持使用std::map&lt;string, int&gt;的想法,其中std::string是卡片值(作为字符串)或“手”,int是出现次数。 在这个主题上,对于有限数量的牌,可以对牌本身进行哈希运算,以快速确定是否有葫芦。 std::unordered_map&lt;hand, bool&gt; full_houses; 之类的。 【参考方案1】:

您可以使用标准算法来编写这样的函数:

bool isFullHouse(vector<string> hand)

   // put all cards matching the first one at the beginning
   auto p = std::partition(hand.begin(), hand.end(), 
                           [first_card = hand[0]] (auto card) 
                             return first_card == card;
                           );
   
   // count cards matching the first one
   auto num = std::distance(hand.begin(), p);

  return (p == 2 or p == 3)                             // 2 or 3 cards 
      && std::equal(hand.begin() + 1, p, hand.begin())  // same card at the beginning
      && std::equal(p + 1, hand.end(), p);              // same card at the end

这里的效率不是主要问题,因为您正在处理一个由 5 个短字符串组成的向量,但这是一个 O(n) 算法。并不是说 n 是相关的,因为您只有 5 张卡,但这里使用的所有算法都是 O(n)

【讨论】:

【参考方案2】:

你也可以让你的生活变得简单并数数卡片。 . .

#include <iostream>
#include <unordered_map>
#include <string>

int main() 

    // Define container
    std::unordered_map<std::string, unsigned int> hand;

    // Read all values and count them
    int i;
    for (std::string card; (i < 5) and (std::cin >> card); hand[card]++, ++i);

    // Show result
    std::cout << (((hand.size() == 2) and ((hand.begin()->second == 2) or (hand.begin()->second == 3))) ? "Full House" : "");

【讨论】:

以上是关于C ++在字符串向量中查找字符串的频率的主要内容,如果未能解决你的问题,请参考以下文章

c语言中如何在一个字符串中查找/出现的位置?需要第一次出现和第二次出现中间的内容和第二次出现和第三

在向量中的字符串中查找字符

c++ 文本文件中查找字符串

在向量中查找字符串的索引

c中常用的字符串操作

在java中查找字符串中字符频率的有效方法:O(n)