首页 > 解决方案 > 如何构造一个可以使用指针成员对指针数组进行排序的函数

问题描述

需要指导/帮助的新 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;
}

标签: c++xcodepointersclangbubble-sort

解决方案


您的排序逻辑有缺陷!

首先,toSwap检查会提前结束排序(在大多数情况下)。例如,一旦i循环运行并且没有找到小于当前i索引的值,搜索就会停止。因此,在 3 个项目的列表中,数量为 (in the unsorted list) 13and 2,然后toSwapfalse在第一个循环的末尾,但3and2仍然需要交换。

所以,首先修复:删除

   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);

具有完全相同的配置文件。


推荐阅读