簡體   English   中英

使用遞歸時出現 substring 搜索問題

[英]Issue with substring search when using recursion

我有一個模擬銀行的程序。 當我選擇存款金額時,它要求我按名稱的一部分搜索用戶。

在這里,我輸入“aar”,這會毫無問題地輸出用戶。

這里沒有問題

現在,我再次啟動程序並輸入“ar”。 這為我提供了所有將“ar”作為我的 substring 的用戶。

同樣,這個 output 沒問題

此后,當我輸入“aar”以輸入 select 我的用戶時,它會再次顯示上一張照片中的所有用戶。

這里顯示的錯誤是一個無限循環

我不確定我到底哪里出錯了。 我仍在學習 C++ 並感謝您的幫助。 這是程序的代碼。

#include <iostream>
#include <iomanip>      //used for setw which is used for formatting cout output
#include <cctype>
using namespace std;

// This Function searches if we have a match or if we have reached the end of string
bool isMatch(char name[], char search_str[])
{
    int i = 0;
    int idx = 0;

    if (search_str[idx] == '\0')
    {
        return true;
    }
    
    if(name[i] == '\0' && search_str[idx] != '\0')
    {
        return false;
    }

    if (name[i] == search_str[idx])
    {
        return isMatch(name + 1, search_str + 1);
    }

    return false;
}

bool IsSubString(char name[], char search_str[])
{
    /*
    Searches the character array for the first occurrence of the sequence specified by its arguments.
    */
    int i = 0;
    int idx = 0;

    for (int i = 0; search_str[idx] != '\0'; i++)
    {
        if (isupper(search_str[idx]))
        {
            search_str[idx] += 32;
        }
    }

    if (name[i] == '\0')
    {
        return false;
    }

    if (name[i] == search_str[idx])
    {
        if (isMatch(name, search_str))
        {
            return true;
        }
    }
    else
    {
        return IsSubString(name + 1, search_str);
    }

    return IsSubString(name + 1, search_str);

}

int select_user(char cust_names[][100], int num_cust)
{
    /*
    Selects a user by searching for part of their name
    */
    char search_user[100];
    int cust_idx = 0;
    int count = 0;
    int selected_user_id;

    while (count != 1)
    {
        cout << "Search user by part of name: ";
        cin.ignore();
        cin.getline(search_user, 100);
        cust_idx = 0;
        count = 0;
        selected_user_id = -1;
        for (cust_idx = 0; cust_idx < num_cust; cust_idx++)
        {
            if (IsSubString(cust_names[cust_idx], search_user))
            {
                selected_user_id = cust_idx;
                cout << "User match: " << cust_names[cust_idx] << endl;
                count++;
            }
        }
        if (count > 1)
        {
            cout << endl << "More than one user found with that substring. Please search again with more characters ************************* " << endl;
        }
        else if (count == 0)
        {
            cout << endl << "No user found with that substring. Please search again *************************" << endl;
        }
    }
    return selected_user_id;
}

void withdraw_from_account(double acct_bal[], double loan_bal[], int account_id, double withdraw_amount)
{
    //withdraw the amount if account has enough balance
    //otherwise, if withdraw amount is more than account balance, charge an overdraft fee and add extra withdrawn amount to loan dues
    double overdraft_fee = 35;
    if (withdraw_amount < 0)
    {
        cout << "Error: Cannot withdraw a negative amount *************************" << endl << endl;
        return;
    }

    acct_bal[account_id] = acct_bal[account_id] - withdraw_amount;

    if (acct_bal[account_id] < 0)
    {
        cout << "Withdrawing amount larger than current account balance. Additional overdraft fee of $35 shall be charged. *************************" << endl << endl;
        loan_bal[account_id] = -acct_bal[account_id] + overdraft_fee;
        acct_bal[account_id] = 0;
    }
}

void deposit_to_account(double acct_bal[], double loan_bal[], int account_id, double deposit_amount)
{
    //deposit the amount if account has no loans
    //otherwise, if deposit amount is more than outstanding loan, add extra amount to account balance
    if (deposit_amount < 0)
    {
        cout << "Error: Cannot deposit a negative amount *************************" << endl << endl;
        return;
    }
    if (loan_bal[account_id] == 0.0)
    {
        acct_bal[account_id] += deposit_amount;
    }
    else
    {
        loan_bal[account_id] -= deposit_amount;
        if (loan_bal[account_id] < 0)
        {
            acct_bal[account_id] = -loan_bal[account_id];
            loan_bal[account_id] = 0;
        }
    }
}

void print_account_details(char cust_names[][100], double acct_bal[], double loan_bal[], int num_cust)
{
    /*
    Prints account statements for all users
    */
    if (num_cust == 0)
    {
        //print header
        cout << "--------------------------------------------------------------------" << endl;
        cout << "\t\t\t ACCOUNT DETAILS " << endl;
        cout << "--------------------------------------------------------------------" << endl;
        cout << "CUSTOMER NAME -> ACCOUNT BALANCE -> LOAN DUE" << endl;
        cout << "--------------------------------------------------------------------" << endl;
        return;
    }

    print_account_details(cust_names, acct_bal, loan_bal, num_cust - 1);
    int print_idx = num_cust - 1;
    cout << std::left << setw(40) << cust_names[print_idx] << " $" << setw(20) << acct_bal[print_idx] << "$" << setw(20) << loan_bal[print_idx] << endl;
}


int print_menu()
{
    /*
    Prints the menu
    */
    int menu_select = -1;

    while (menu_select < 0 || menu_select > 3)
    {
        cout << "--------------------------------------------------------------------" << endl;
        cout << "\t\t MENU" << endl;
        cout << "--------------------------------------------------------------------" << endl;
        cout << "1: Show Account Details" << endl;
        cout << "2: Deposit amount to account" << endl;
        cout << "3: Withdraw amount from account" << endl;
        cout << "0: Exit" << endl;
        cout << "--------------------------------------------------------------------" << endl;
        cout << "Select menu option [1, 2, 3, 0] : ";
        cin >> menu_select;
        cout << "--------------------------------------------------------------------" << endl;
        if (menu_select < 0 || menu_select > 3)
            cout << "Error: Incorrect menu item selected. Please select again *************************" << endl << endl;
    }

    return menu_select;
}



int main()
{
    const int num_customers = 5;
    char customer_names[num_customers][100] = {
        "john fitzgerald kennedy",
        "william shakespeare",
        "salvador felipe jacinto dali domenech",
        "elvis aaron presley",
        "elizabeth alexandra mary windsor" };


    double customer_account_balances[num_customers] = { 100.5, 120.75, 50.2, 150.15, 200.99 };
    double customer_loan_dues[num_customers] = { 0.0, 0.0, 0.0, 0.0, 0.0 };


    cout << "************************* Welcome to BANK OF ANTARCTICA *************************" << endl << endl << endl;



    print_account_details(customer_names, customer_account_balances, customer_loan_dues, num_customers);
    cout << endl << endl << endl;
    double amount;
    int acct_id;
    int menu_select = -1;
    while (menu_select != 0)
    {
        menu_select = print_menu();
        switch (menu_select)
        {
        case 1:     // Show Account Details
            print_account_details(customer_names, customer_account_balances, customer_loan_dues, num_customers);
            cout << endl << endl << endl;
            break;
        case 2:     // Deposit amount to account
            acct_id = select_user(customer_names, num_customers);
            cout << "Please enter amount to DEPOSIT into the account of: " << customer_names[acct_id] << " :: $";

            cin >> amount;
            deposit_to_account(customer_account_balances, customer_loan_dues, acct_id, amount);
            print_account_details(customer_names, customer_account_balances, customer_loan_dues, num_customers);
            cout << endl << endl << endl;
            break;
        case 3:     // Withdraw amount from account
            acct_id = select_user(customer_names, num_customers);
            cout << "Please enter amount to WITHDRAW from the account of: " << customer_names[acct_id] << " :: $";

            cin >> amount;
            withdraw_from_account(customer_account_balances, customer_loan_dues, acct_id, amount);
            print_account_details(customer_names, customer_account_balances, customer_loan_dues, num_customers);
            cout << endl << endl << endl;
            break;
        }
    }


    cout << endl << endl << "Final Details:" << endl;
    print_account_details(customer_names, customer_account_balances, customer_loan_dues, num_customers);
    cout << endl << endl << endl;

    cout << "THANK YOU!!! for using BANK OF ANTARCTICA services" << endl;

    return 0;
}

仔細看看這個循環:

int i = 0;
int idx = 0;

for (int i = 0; search_str[idx] != '\0'; i++)
{
    if (isupper(search_str[idx]))
    {
        search_str[idx] += 32;
    }
}

循環條件檢查search_str[idx] != '\0' ,但循環中無處更改idx (您只更改i )。 因此,只要循環條件為真,您就會陷入永無止境的循環。

我通常建議在將IsSubstring function 放入更大的程序之前對其進行隔離測試(使用一些測試框架或只是一個簡單的程序在幾個測試輸入上計算 IsSubstring 並檢查其結果)。

我想這是某種家庭作業? 否則我會建議完全擺脫你的 IsMatch/IsSubString 方法並使用std::string和它的find function (或者 將來可能contains )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM