如何在C ++中搜索字符串数组

时间:2013-12-09 02:32:11

标签: c++ arrays sorting

我是C ++世界的新手,所以如果我没有正确地提出这个问题,我会事先道歉。

我正在尝试用C ++完成作业。它有多个需要完成的任务。以下是任务:1)从文本文件中提取名称。 2)显示它们(未分类)3)再次显示它们(已排序)4)搜索列表并查找以相同字母开头的名称并计算它们并显示它们。

我能够做到1到3号而没有多少问题。但我难以理解如何搜索字符串数组并查找具有相同字母的名称来计算和显示它们?请记住,我是C ++的新手,并希望在正确的方向上轻推,以便对其进行排序!

好的,所以我能够创建一个函数来对名称进行排序

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

void selectionSort(string[], int);
void showNames(const string[], int);
void extractNames(string[], int);
bool searchForNames(string[], int);
int binarySearch(const string[], int, char);

int main()
{

const int NUM_NAMES = 20;
string names[NUM_NAMES];


ofstream outputFile;
outputFile.open("names.txt");

outputFile << "Collins, Bill" << endl;
outputFile << "Smith, Bart" << endl;
outputFile << "Allen, Jim" << endl;
outputFile << "Griffin, Jim" << endl;
outputFile << "Stamey, Marty" << endl;
outputFile << "Rose, Geri" << endl;
outputFile << "Taylor, Terry" << endl;
outputFile << "Johnson, Jill" << endl;
outputFile << "Allison, Jeff" << endl;
outputFile << "Looney, Joe" << endl;
outputFile << "Wolfe, Bill" << endl;
outputFile << "James, Jean" << endl;
outputFile << "Weaver, Jim" << endl;
outputFile << "Pore, Bob" << endl;
outputFile << "Rutherford, Greg" << endl;
outputFile << "Javens, Cathy" << endl;
outputFile << "Pike, Gordon" << endl;
outputFile << "Holland, Beth" << endl;

outputFile.close();

//call function that extracts names from the text file and assigns them to
//an array of names so it can be manuplated later
extractNames(names, NUM_NAMES);


//Display names in unsorted order
cout << "Unsorted names are: " << endl;
cout << "------------------- " << endl;
showNames(names, NUM_NAMES);

cout << endl;
cout << endl;

//Sort the names
selectionSort(names, NUM_NAMES);

//Display names in sorted order
cout << "Sorted names are: " << endl;
cout << "----------------- " << endl;
showNames(names, NUM_NAMES);

cout << endl;


searchForNames(names, NUM_NAMES);

}

void showNames(const string array[], int size)
{
    for(int count = 0; count < size; count++)
        cout << array[count] << endl;
}

void selectionSort(string array[], int size)
{
    int startScan;
    string MinValue;
    int minIndex;
    for(startScan=0; startScan < (size-1); startScan++)
{
    minIndex=startScan;
    MinValue = array[startScan];
    for(int index=startScan+1; index < size; index++)
    {
        if(array[index]<MinValue)
        {
            MinValue = array[index];
            minIndex = index;
        }
    }

    array[minIndex] = array[startScan];
    array[startScan] = MinValue;
}

}
void extractNames( string names[], int size)
 {
int count =0;
ifstream inputFile;
inputFile.open("names.txt");
while(count<size && getline(inputFile, names[count]))
{
    count++;
}
inputFile.close();
}

bool searchForNames(string names[], int size)
{
    for (char value = 'A'; value < 'Z'; value++)
    {
        cout << "Names starting with " << value << " are: "<< endl;
         binarySearch(names, 20, value);
}
return true;
}
int binarySearch(const string array[], int elements, char value)
{
//string abc;
//abc=static_cast<string>(&value);
int first = 0, last = elements - 1, middle , position = -1;
bool found = false;
while(!found && first <= last)
{
    middle = (first + last) / 2;
    if(array[middle] == &value)
    {
        found = true;
        position = middle;
    }
    else if(array[middle] > &value)
        last = middle - 1;
    else
        first = middle + 1;
}

return position;
}

我仍然无法做到这一点:创建一个函数来计算每个字母开头的姓数,并每次输出名称和名称总数。此函数应按值传递数组,并按值传递数组的大小。该函数应输出以特定字母开头的名称,然后输出名称总数。不要输出没有任何名称的字母的结果,例如,没有以B开头的名称,因此不应为此字母生成输出。这是我第一次在StackOverflow中提问,所以如果我无法正确解释,我会道歉。

4 个答案:

答案 0 :(得分:1)

这是经典的第一个C ++任务,我认为这是为了让您习惯标准模板库中提供的各种工具。

首先,排序。名为<algorithm>的{​​{1}}标题中有一个函数可以为您执行此操作。查看此reference以了解更多相关信息。它会严重缓解你的痛苦。

要进行搜索,请尝试std::find

接下来,您需要一个保持字母(std::sort)的查找以及每个字符作为名称的第一个字母出现的次数。 std::map<char, int>是一个为您执行此操作的类。 chars的简单for循环,其中char_count[name[0]]++;是地图,可能就是您想要的。

答案 1 :(得分:0)

如果你需要找到所有匹配项,那么线性搜索数组可能更简单,而不是使用二进制算法。这种方法较慢但更容易实现,如果你是C ++的新手,那就可以了。

当您遍历数组时,您可以构建一个匹配数组并返回该数组。

答案 2 :(得分:0)

如果我正确理解了第4步,如果你有一个列表(“安德鲁”,“安”,“戴夫”,“多米尼克”,“唐”),你想要输出如下内容:2 A,3 D 。正确吗?

如果是这种情况,那么您只需循环检查每个字符串的第一个字符的排序列表。如果它与前一个字符相同,请增加计数。如果不是,则输出前一个字符并重置计数。对于循环的开始和结束有一点特殊的处理,你已经完成了。

顺便说一下,我认为不需要二元搜索,还是有更多的分配?

答案 3 :(得分:0)

像这样的东西

  std::vector<std::vector<std::string>> resultsPerLetter(26);
  for (int i = 0; i<elements; ++i) {
      resultsPerLetter[tolower(names[i][0]) - 'a'].push_back(names[i]);
      }

  for (int i = 0; i<26 ; ++i) {
      if (resultsPerLetter[i].size()!=0) {
          std::cout<<"number of names starting with '"<<char(i+'a')<<"' : " << resultsPerLetter[i].size() << "\n";
          std::cout<<"The names : \n";
          for(int j = 0, j_e = resultsPerLetter[i].size(); j<e; ++j) {
               std::cout << " - " << resultsPerLetter[i][j] << "\n";
               }
          }
     }