c++ - 如何构造一个可以使用指针成员对指针数组进行排序的函数
问题描述
需要指导/帮助的新 CS 学生。我试图按在用户端挑选的班级成员对我的pRecordBook数组进行排序。但是由于某种原因,在执行我的比较时只是作废或不采取。
铿锵声 11.0.3 Xcode
#include <iostream>
#include <fstream>
#include <string>
const int MAX_RECORDS = 200;
class Record{ // Record Class with members
private:
std::string id;
std::string name;
int quantity;
double price;
public:
Record();
const std::string getID();
const std::string getName();
const double getPrice();
const int getQuantity();
void setID(std::string num);
void setName(std::string input);
void setQuantity(int quantity);
void setPrice(double price);
void setRecord(std::string id, std::string name, int quantity, double price);
std::string displayRecord();
};
void readFile(Record recordBook[], Record *pRecordBook[], std::string file, int &count);
void displayArray(Record recordBook[], const int count);
void displayArray(Record *pRecordBook[], const int count);
void sortArray(Record *pRecordBook[], const int count, int selection);
std::string searchRecord(Record *pRecordBook[], const int count, std::string &input);
std::string searchRecord(Record *pRecordBook[], const int count, std::string &input);
void printReport(Record recordBook[], const int count);
void displayOptions(int &choice);
int main(int argc, const char * argv[]) {
int selection = 0;
int subSelection = 0;
std::string inputID = "";
std::string inputName = "";
int count = 0;
Record recordBook[MAX_RECORDS];
Record *pRecordBook[MAX_RECORDS];
std::string fileName = "testFile.txt";
readFile(recordBook, pRecordBook, fileName, count);
displayOptions(selection);
while(selection != 0){
switch(selection){
case 1:
std::cout << "\nPrinting Unsorted Inventory";
displayArray(recordBook, count);
break;
case 2:
std::cout << "\nSort By\n1. ID\n2. Name\n3. Quantity\n4. Price\nSelection: ";
std::cin >> subSelection;
while(subSelection < 1 || subSelection > 4){
std::cout << "\nPlease a selection from 1-4\nTry Again: ";
std::cin >> subSelection;
}
sortArray(pRecordBook, count, subSelection);
displayArray(pRecordBook, count);
break;
case 3:
std::cout << "\nSearch for item by:\n1. ID\n2. Name\nSelection: ";
std::cin >> subSelection;
if(subSelection > 2 || subSelection < 1){
std::cout << "\nPlease a selection of 1 or 2\nTry Again: ";
std::cin >> subSelection;
}else{
if(subSelection == 1){
std::cout << "\nEnter ID to search for: ";
std::cin >> inputID;
searchRecord(pRecordBook, count, inputID);
}else{
std::cout << "\nEnter the Name to search for: ";
std::cin >> inputName;
searchRecord(pRecordBook, count, inputName);
}
}
break;
case 4:
printReport(recordBook, count);
break;
default:
std::cout << "\nInvalid Option, Try Again\n";
break;
}
displayOptions(selection);
}
if(selection == 0){
std::cout << "\nTerminated Program. Goodbye\n";
}
return 0;
}
// Get Functions
const std::string Record::getID(){ return id;}
const std::string Record::getName(){ return name;}
const double Record::getPrice(){ return price;}
const int Record::getQuantity(){ return quantity;}
// Set Functions
void Record::setID(std::string num){
this->id = num;
}
void Record::setName(std::string input){
std::string name;
for(char letter: input){
name += toupper(letter);
}
this->name = name;
}
void Record::setQuantity(int quantity){
this->quantity = quantity;
}
void Record::setPrice(double price){
this->price = price;
}
// Contsructor for the initialization of "recordBook Array"
Record::Record(){
id = "";
name = "";
quantity = NULL;
price = NULL;
}
// Function to set the Entire class at once - Called in readFile function
void Record::setRecord(std::string id, std::string name, int quantity, double price){
setID(id);
setName(name);
setQuantity(quantity);
setPrice(price);
}
// Reads file, checks if correct file, checks if its empty, grabs values and stores them in class Record on the recordBook array
void readFile(Record recordBook[], Record *pRecordBook[], std::string fileName, int &count){
std::ifstream inFile;
std::ofstream outFile;
inFile.open(fileName, std::ios::in);
outFile.open("errorFile.txt", std::ios::out | std::ios::app);
while(!inFile){
std::cout << "\nError: Could Not Open File\nTry Again: ";
std::cin >> fileName;
inFile.open(fileName, std::ios::in);
}
while(inFile.peek() == EOF){// Checking if file is empty
std::cout << "\nError: File is Empty\nTry Again: ";
std::cin >> fileName;
inFile.open(fileName, std::ios::in);
}
std::string id;
std::string name;
int quantity;
double price;
while(inFile >> id >> name >> quantity >> price && !(inFile.eof())){
if(price == 0 || quantity == 0){
outFile << id << " " << name << " " << quantity << " " << price << "\n";
}else{
recordBook[count].setRecord(id, name, quantity, price);
pRecordBook[count] = &recordBook[count];
count++;
}
if(count == MAX_RECORDS){
std::cout << "\nProgram Storage Full. Stopping on line " << MAX_RECORDS << "\nUsing values grabbed. . . ";
break;
}
};
outFile.close();
inFile.close();
}
std::string Record::displayRecord(){ // Function to display individual Record
return this->id + " " + this->name + " " + std::to_string(this->quantity) + " " + std::to_string(this->price);
}
void displayArray(Record recordBook[], const int count){ // Function to display all Records in RecordArray
for(int i = 0; i < count; i++){
std::cout << "\nItem: " << (i+1) << " " << recordBook[i].displayRecord();
}
std::cout << "\n";
}
void displayArray(Record *pRecordBook[], const int count){ // Function display all Record in PointerArray
for(int i = 0; i < count; i++){
std::cout << "\n" << pRecordBook[i]->displayRecord();
}
std::cout << "\n";
}
我已经向后工作,甚至插入了我的常规数组,选择了一个条件,将其硬编码在if 语句中。- 繁荣工程
然后我包含了switch 语句,因为我想到了break;在开关中导致我被踢出嵌套循环,从而杀死了这样做的功能。- 不工作
当我插入指针数组时,比较失败。有没有我失踪的演员?
感谢您的时间!
// Function to sort array depending on user selection
void sortArray(Record *pRecordBook[], const int count, int selection){
bool toSwap;
bool condition;
Record *pTemp;
for(int i = 0; i < count; i++){
toSwap = false;
for(int j = i + 1; j < count-i-1; j++){
// Seems like our problem is the sorting is not being saved
// Possibly grabbing the data incorrectly or might be the sorting itself that is wrong
switch(selection){
case 1:
condition = pRecordBook[j]->getID() < pRecordBook[i]->getID();
break;
case 2:
condition = pRecordBook[j]->getName() < pRecordBook[i]->getName();
break;
case 3:
condition = pRecordBook[j]->getQuantity() < pRecordBook[i]->getQuantity();
break;
case 4:
condition = pRecordBook[j]->getPrice() < pRecordBook[i]->getPrice();
break;
default:
std::cout << "\nError concurred - sorting bv default: Name";
condition = pRecordBook[j]->getName() < pRecordBook[i]->getName();
break;
}
if(condition){
pTemp = pRecordBook[i];
pRecordBook[i] = pRecordBook[j];
pRecordBook[j] = pTemp;
toSwap = true;
}
}
if(toSwap == false)
break;
}
}
std::string searchRecord(Record *pRecordBook[], const int count, std::string id){ // Function searches for ID
for(int i = 0; i < count; i++){
if(id == pRecordBook[i]->getID())
return "\nRecord Found at Index " + std::to_string(i) + ": " + pRecordBook[i]->displayRecord();
}
return "\nRecord Not Found!";
};
std::string searchRecord(Record *pRecordBook[], const int count, std::string &input){ // Function searches for Name
for (int i = 0; i < count; i++) {
if(input == pRecordBook[i]->getName()){
return "\nRecord Found at Index " + std::to_string(i) + ": " + pRecordBook[i]->displayRecord();
}
}
return "\nRecord Not Found!";
};
void printReport(Record recordBook[], const int count){ // Prints Inventory Report
double totalValue = 0.0;
for(int i = 0; i < count; i++)
totalValue += recordBook[i].getPrice();
std::cout << "Report:\nTotal Number of items: " << std::to_string(count) << "\nTotal worth of Inventory: $";
std::cout << std::setprecision(2) << std::fixed << totalValue;
};
void displayOptions(int &choice){ // Displays Main Menu
std::cout
<< "\n1: Print Inventory Unsorted"
<< "\n2: Sort in ascending order by any field"
<< "\n3: Search for an item by ID or name"
<< "\n4: Print Report with total count and worth of inventory"
<< "\nChoose an Option: ";
std::cin >> choice;
}
解决方案
您的排序逻辑有缺陷!
首先,toSwap
检查会提前结束排序(在大多数情况下)。例如,一旦i
循环运行并且没有找到小于当前i
索引的值,搜索就会停止。因此,在 3 个项目的列表中,数量为 (in the unsorted list) 1
,3
and 2
,然后toSwap
将false
在第一个循环的末尾,但3
and2
仍然需要交换。
所以,首先修复:删除
if (toSwap == false)
break;
因此,您可以完全toSwap
删除变量!
其次,您的内部 ( j
) 循环的“测试”条件真的很奇怪!每次都必须跑到列表的末尾。
所以,第二个修复:改变
for(int j = i + 1; j < count-i-1; j++){
至
for(int j = i + 1; j < count; j++){
我已经在以下输入文件上测试了您给定的代码代码,并进行了这些更改,并且它可以工作,据我所知:
123 Cheese 5 12.30
212 Mutton 1 44.67
202 Chicken 3 12.78
363 Orange 5 6.22
327 Lemon 10 8.13
124 Butter 4 6.45
(当然,我不知道你的实际数据值是多少,所以我编了一些!)
编辑:可能是一个新问题,但您的“搜索项目...”选项也存在问题,因为编译器无法正确区分对这两个searchRecord
函数的调用。两个调用:
searchRecord(pRecordBook, count, inputID);
searchRecord(pRecordBook, count, inputName);
具有完全相同的配置文件。
推荐阅读
- python - 避免使用 sqlalchemy 查询在层次结构中加载特定类
- java - Java制作数字文件的二维列表对象
- types - 为 x64 构建但 x86 正常时类型转换无效
- python - 初始化其他变量(使用它)后变量的原始值丢失
- c++ - 我的二维数组没有读取我的文本文件并正确输出
- r - 安装 xgboost h2o r
- python - 在格子中计算大小为 l 的窗口中的节点
- c# - 无法使用随机数生成器和 if 语句将类型“int”隐式转换为“bool”
- python - 以下代码行是什么意思以及python解释器如何处理这个
- c# - Swashbuckle 没有在 PCF 上定义操作。工作本地开发