为啥我的线性搜索总是返回 false,即使该项目在数组中?

Posted

技术标签:

【中文标题】为啥我的线性搜索总是返回 false,即使该项目在数组中?【英文标题】:Why is my linear search always returning false, even if the item is in the array?为什么我的线性搜索总是返回 false,即使该项目在数组中? 【发布时间】:2020-11-24 23:08:38 【问题描述】:

我正在上 C++ 简介课程,我们的一项任务是创建一个在线商店。我们的问题之一是为库存创建一个搜索功能,使用线性搜索,然后显示该商品的相应价格、库存和可运输性。

出于某种原因,无论我如何尝试调整它,它总是返回 false 进行搜索,并且商店不提供该商品,即使我输入了我知道的商品项目数组。

例如,如果我在getline 中键入Moon Pie(在我的数组中),它仍会以-1 的形式返回,就像不是一样。这段代码有什么明显错误吗?

这是我的 inputInventory.txt

Moon Pie    3.50    15  1
Cosmic Brownie  2.00    12  0
Moon Shine  7.00    7   1
Astronaut Icecream  4.00    11  1
Neptune Nuggets 2.50    30  1
Venus Vodka 6.50    10  1
Planet Pop  4.50    20  0
Starry Salad    3.00    15  0
Celeste Cakes   5.00    11  1
Plasma Potion   9.99    4   1
Star Fruit  2.50    10  1
Sun-dae 7.00    20  0
Moon Cheese 5.00    10  1
Milky Way Milkshake 6.50    5   0
Pluto Pie   7.00    9   10
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

const int MAX = 15;
void searchInventory(string itemNames[], double itemCost[], int itemNoShip[MAX][2]);
int linearSearch(string arr[], int size, string value);

int main() 
  int input;
  string items[MAX];
  double priceItems[MAX];
  int noItems[MAX][2];

  cout << "\n1. Read in Inventory\n";
  cout << "2. Display Inventory\n";
  cin >> input;

  while (input > 2 || input < 1) 
    cout << "An error has occured. Please input a value 1 - 2. >> ";
    cin >> input;
  

  switch (input) 
    case 1:
      if (readInventory(items, priceItems, noItems) == true) 
        cout << "\nReading the file...\n";
      
      break;
    case 2:
      searchInventory(items, priceItems, noItems);
      break;
  


bool readInventory(string itemNames[], double itemCost[], int itemNoShip[MAX][2]) 
  bool fileRead = false;
  ifstream inputFile; // Pointer
  inputFile.open("inputInventory.txt");

  if (inputFile) // Test if file opened
  
    for (int row = 0; row < MAX; row++) 
      getline(inputFile, itemNames[row], '\t');
      inputFile >> itemCost[row];
      inputFile >> itemNoShip[row][0];
      inputFile >> itemNoShip[row][1];
    

    fileRead = true;
    inputFile.close();

  
  return fileRead;


void searchInventory(string itemNames[], double itemCost[], int itemNoShip[MAX][2]) 
  string search;
  int result;
  int position;
  cout << "Please type the name of the item you are looking for. > ";
  cin.ignore();
  getline(cin,search);

  result = linearSearch(itemNames, MAX, search);

  cout << result;

  if (result >= 0) 
    cout << "\nYour item was found!\n";
    cout << itemNames[result] << itemCost[result] << itemNoShip[result][0] << "Shippable:" << itemNoShip[result][1];
  
  else 
    cout << "\nThis item was not found in the list.";
  


int linearSearch(string arr[], int size, string value) 
  int position;
  int index;
 
  for (index = 0; index < size; index++) 
    if (arr[index] == value) 
      position = index;
     
    else 
      position = -1;
    
        
  
  return position;

【问题讨论】:

linearSearch() LGTM,您能否分享一个完整、最小且可重现的示例?例如,您的数组是如何填充的? value 是否在调用搜索方法之前存储了期望值?你确定position 在搜索方法中被初始化了吗? 添加到 gsamaras,我们需要知道你传递给这个函数的内容。 linearSearch 如果for 循环至少没有执行一次,则返回一个未初始化的值。如果size 为 0 会怎样? 请提供minimal reproducible example。 除此之外,我们看到的只是变量。我们没有看到正在使用的实际值。因为它们是从cin 输入的。如果您没有输入您声称正在使用的值怎么办?您应该对这些值进行硬编码,而不是使用 cin 来验证 linearSearch 函数是否确实有效。或者您可以简单地输出:cout &lt;&lt; "\nThis item " &lt;&lt; search &lt;&lt; " was not found in the list.";,这样您就可以看到您实际搜索的内容。 【参考方案1】:
for (index = 0; index < size; index++) 
        if (arr[index] == value) 
          position = index;
         
        else 
          position = -1;
        
      

此循环不断覆盖position

除非你想要的元素是数组中的最后一个元素,否则在找到它后立即 next 元素将导致 position 再次设置为 -1(除非一个也匹配?)。

一旦找到匹配项,您就应该停止循环(或者至少停止更新position)。

此外,建议将整个循环体包裹在 大括号中,因为这是常规做法,也是人们期望看到的,从而使代码更易于阅读和理解。

怎么样:

int linearSearch(string arr[], int size, string value)

    for (int index = 0; index < size; index++)
    
        if (arr[index] == value)
            return index;
    
    
    return -1;

【讨论】:

【参考方案2】:

一旦找到该项目,您应该跳出 for 循环,否则循环将继续并覆盖 position。编辑:根据PaulMcKenzie的评论,你应该用一个值初始化position,这样它就不会返回垃圾值。

int linearSearch(string arr[], int size, string value) 
  int position = -1;
  int index;
 
  for (index = 0; index < size; index++) 
        if (arr[index] == value) 
          position = index;
          break;
        
  
      
  return position;

【讨论】:

你应该初始化positionsize 为 0 将导致 position 返回 who-knows-what。【参考方案3】:

问题是cin.ignore(),由于第一个参数的默认值为1,所以第一个字母总会被取出来。因此,如果有人输入“Moon Pie”,搜索中的值将是“oon Pie”。

【讨论】:

我也假设你是using namespace std,否则“cin”和“cout”也是错误的。 他们可能忽略了先前未见过的格式化提取的换行符。 嘿,谢谢!出于某种原因,当我自己使用 getline 时,它​​不允许我输入任何内容。我需要使用忽略函数来实际输入一行。 我建议你使用std::cin &gt;&gt; search。这将允许您输入所述输入并将其存储在 search 变量中。 @UmbraSicaro 只有一个词。一般来说getline比较好。

以上是关于为啥我的线性搜索总是返回 false,即使该项目在数组中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Receiver for Charge 状态总是返回 false?

Android:为啥 Radio Group 中的 Radio Button 总是为任何选定的项目返回 false?

为啥我的 ACF 自定义字段总是返回 false 或数组?

为啥 WinAPI FormatMessage 失败,总是返回 false

为啥我总是得到单例bean,即使我使用proxyBeanMethods = false?

Auth::attempt 总是返回 false,即使输入和哈希正确