【问题标题】:Searching a array of strings搜索字符串数组
【发布时间】:2012-01-13 16:58:30
【问题描述】:

这个程序的主要目的是从文件中读取多达 100 个名称,使用冒泡排序进行排序,然后通过二进制搜索搜索输入的名称。

似乎一切正常,但当我输入列表中的名称时,没有任何反应,只是提示我再次输入名称。

在猫王的列表中说出一个名字。系统提示我输入名称。我输入猫王。我应该收到猫王是你的朋友。没有发生。任何帮助表示赞赏。

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

void bubblesort(string[], const int);
void search(string[], const int);
int sub = 0;

int main()
{
 const int maxsize = 100;
 string friendArray[maxsize];

 ifstream friends;
 friends.open("myFriends.dat");

 while (sub < maxsize && getline(friends, friendArray[sub]))
   sub++;


 bubblesort(friendArray, sub);
 search(friendArray, maxsize);


 system("pause");
 return 0;
}



void bubblesort(string *array, const int size)
{
    bool swap;
    string temp;

    do
    {
        swap = false;
        for (int count = 1; count < (size - 1); count++)
        {
            if(array[count-1] >array[count])
            {
                temp = array[count-1];
                array[count-1] = array[count];
                array[count] = temp;
                swap = true;
            }
        }
    }
    while(swap);

}

void search(string *array, int size)
{
    int first = 0;
    int last = size - 1;
    int middle;
    string name;
    bool friends = false;

    do
    {
     cout<<"Please enter a name or END to terminate:";
     cin>>name;
    }
    while(!friends && first <= last && name != "END");
    {
        middle = (first + last) / 2;
        if (array[middle] == name)
            {
                friends = true;
                cout<<array[middle]<<" is my friend."<<endl;
            }
        else if (array[middle] > name)
            last = middle - 1;
        else
            last = middle + 1;
    }
}

【问题讨论】:

  • 根据答案修复问题不是一个好主意,因为它几乎使每个答案都无效并使问题无用(因为那里 is 修复后没有问题)。除非更改只是装饰性的,否则您应该提出另一个问题,如果不再相关,则删除此问题。
  • 好的,我将开始一个新问题。

标签: c++ arrays search binary-search


【解决方案1】:

在您的 search() 函数中,do { } while; { } 构造存在缺陷。它会编译,但它不会做你想要的。我做了一些更改并重新排列了您的代码,使其更有意义。

void search(string *array, int size)
{
    string name;

    for (;;)
    {
        cout<<"Please enter a name or END to terminate:";
        getline(cin, name);
        if (name == "END") break;

        int first = 0;
        int last = size - 1;
        bool friends = false;

        while (!friends && first <= last)
        {
            int middle = (first + last) / 2;
            if (array[middle] == name)
            {
                friends = true;
                cout<<array[middle]<<" is my friend."<<endl;
            }
            else if (array[middle] > name)
                last = middle - 1;
            else
                first = middle + 1;
        }
    }
}

int main () // test the search() function
{
    string array[] = { "bird", "cat", "dog", "horse", "loon", "zebra" };
    search(array, 6);
}

所以,这对家庭作业有帮助吗?我应该删除这个吗?

【讨论】:

  • 这太棒了,我觉得我从视觉示例中学到了很多东西,因为这就是我从书中学到的一切。它在向我解释算法方面做得不是很好。
  • @sircrisp:你很亲密。我刚刚重新排列了您的代码,因此有一个提示输入搜索名称的外部循环和一个执行二进制搜索的内部循环。
  • 我更改了代码以匹配您的代码,现在在我输入列表中的名称后,程序什么也不做,但我听到我的 CPU 风扇越来越响。
  • @sircrisp:在调用搜索函数之前检查你的排序代码并确保数组是有序的。
  • @sircrisp:我添加了一些测试代码,这个search() 似乎可以工作。输入数组必须按升序排序。
【解决方案2】:

我发现您在两种都找不到匹配项的情况下设置last 很有趣。

您应该做的第一件事是想想这意味着什么,轻推、轻推、眨眼、眨眼:-)

您还应该将 已使用 元素的数量传递给 search,而不是数组的大小(因为您可能没有使用完整的数组)。

【讨论】:

  • 两个鞋楦只是一个错字,但是一旦我解决了我要解决的问题,这可能会破坏一些东西。
【解决方案3】:

我猜

search(friendArray, maxsize);

应该是

search(friendArray, sub);

二分查找的输入条件是查找到的数组是有序的。您的数组如下所示:

Aaron Burr
Bill Cosby
Celine Dion
...
Zachary Taylor
""
""
""
""

etc.

由于空字符串不小于非空字符串,所以friendArray[0..maxsize]不排序,而数组friendArray[0..sub]是。


编辑:我也刚刚注意到您的二进制搜索算法存在缺陷。再次查看您的源材料(教科书、维基百科等)。 first 不应该在你的循环中更新吗?

【讨论】:

    【解决方案4】:

    Operator >> 从流中读取格式化数据,即丢弃空格。当你说cin &gt;&gt; name; 并输入“Elvis Presley”时,只有“Elvis”会存储在name 中。

    你需要的是getline(cin, name);

    【讨论】:

    • 感谢您发现这个问题仍然存在。
    【解决方案5】:

    想想如果friends 数组的长度为3 会发生什么。如果我没记错的话会有问题。

    另外推荐使用更安全的数据类型,比如vector&lt;string&gt;,那么你就不需要关心输入文件中太多的数据了。此外,搜索功能会让您的生活变得更轻松,因为您可以使用迭代器并且不需要传递数组的大小。

    看看人们在其他答案中对cin 的评价。

    【讨论】:

    • 我已将 cin 更改为 getline 并将 search 更改为 search(friendArray, sub)。以前从未使用过向量或已经了解它们,所以我想尽可能少地修改我现有的代码。
    • @sircrisp 好。想想如果friends 的长度是3 会发生什么。我明白你的意思,把它当作一个建议,以后再看看,这是值得的。
    【解决方案6】:

    这是一个do-whie循环:

    do
    {
     cout<<"Please enter a name or END to terminate:";
     cin>>name;
    }
    while(!friends && first <= last && name != "END");
    

    代码基本上会永远循环(friends 永远不会是 true,first 永远不会是 > last),提示您输入名称,直到您终止程序或输入“END”。

    这个:

    {
        middle = (first + last) / 2;
        if (array[middle] == name)
            {
                friends = true;
                cout<<array[middle]<<" is my friend."<<endl;
            }
        else if (array[middle] > name)
            last = middle - 1;
        else
            last = middle + 1; 
    }
    

    在循环条件为假之前(在这种情况下,直到您输入“END”)才会有机会执行。

    【讨论】:

    • 我把 while 改成了 while(!friends && name != "END");虽然没有运气。我已经为此工作了 4 个小时,我无法再确定任何事情了,我的逻辑已经死了。
    【解决方案7】:

    您说除了输入要搜索的名称外,一切似乎都正常。实际上,您进入了重点。您的二进制搜索代码中有一个错误。而这个话题的第一个答案就是朝着这个方向。

    如果在二分查找中使用数组,则在每个查找阶段都必须将其分成两部分。

    例如在一个阶段中,如果当前部分标记如下:第一 - 中间 - 最后在下一个阶段,部分将介于第一 - 中间-1 或中间+1 - 最后。

    所以

        else if (array[middle] > name)
          last = middle - 1;
        else 
          last = middle + 1;
    

    必须

      else if (array[middle] > name)
          last = middle - 1;
      else 
          first = middle + 1;
    

    【讨论】:

      【解决方案8】:

      您的排序中有一个错误。

      【讨论】:

      • 注意指出哪一部分是错的?我之前收到了有关排序的帮助。
      • @sircrisp,抱歉,这看起来太像家庭作业了,我无法给出简单的答案。但是单步执行代码,看看哪个元素被遗漏了。
      【解决方案9】:

      问题在于函数搜索。将 cin>>name 之后的 } 移动到函数的末尾,如下所示:

      void search(string *array, int size)
      {
          int first = 0;
          int last = size - 1;
          int middle;
          string name;
          bool friends = false;
      
          do
          {
              cout<<"Please enter a name or END to terminate:";
              cin>>name;
      
              while(!friends && first <= last && name != "END");
              {
                  middle = (first + last) / 2;
                  if (array[middle] == name)
                  {
                      friends = true;
                      cout<<array[middle]<<" is my friend."<<endl;
                  }
                  else if (array[middle] > name)
                      last = middle - 1;
                  else 
                      last = middle + 1;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-10-06
        • 1970-01-01
        • 2013-04-11
        • 1970-01-01
        • 2011-07-04
        • 2022-01-08
        • 2013-03-31
        • 1970-01-01
        相关资源
        最近更新 更多