需要帮助查找膳食生成器中的问题

问题描述 投票:0回答:1

我有一个膳食生成器,可以每周生成 4 天的膳食。有些餐我想算作两餐,因为它们会产生剩菜。我也有一些成组的餐食(香蒜酱、意大利面和意大利饺子都是意大利面),我不想在输出中一起出现。如果未选择面食餐食,则输出中应显示 4 餐食。如果输出中出现一顿意大利面餐,则总共应有 3 餐:意大利面餐和 2 顿非意大利面餐。这意味着不能选择面食作为第四餐。

我的代码分为3个文件: 主.cpp

#include "include\mealSelector.h"

int main() {
    std::vector<std::string> meals = {
        "Spaghetti", "Pesto", "Frozen Pizza", "Nachos", "Potato Skins",
        "Quesadillas", "Hoagies", "Lunch meat sandwiches", "Brats",
        "Chicken, Potatoes and Broccoli", "Taquitos and Mini Corn dogs",
        "App Night", "Grilled Cheese", "Mac & Cheese", "Tortellini"
    };

    MealSelector mealSelector(meals);
    mealSelector.shuffleMeals();
    mealSelector.selectMeals();

    return 0;
}

餐选择器.cpp

#include "include/MealSelector.h"
#include <algorithm>

MealSelector::MealSelector(const std::vector<std::string>& initialMeals)
    : meals(initialMeals), mealCount(0), pastaAllowed(true) {} // Initialize [Meal Group]Allowed here

void MealSelector::shuffleMeals() {
    std::random_device rd{};
    std::seed_seq ss{ rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd() };
    std::mt19937 mt{ ss };
    std::shuffle(meals.begin(), meals.end(), mt);
}

void MealSelector::selectMeals() {
    for (const auto& meal : meals) {
        if (mealCount >= 4) {
            break; // Exit the loop once we have 4 meals
        }

        if (canSelectPastaMeal(meal) && ((mealCount < 3) || (mealCount == 3 && pastaAllowed))) {
            handleSelectedPastaMeal(meal);
        } else {
            handleRegularMeal(meal);
        }
    }
}

void MealSelector::printAndAddMeal(const std::string& meal) {
    std::cout << meal << std::endl;
    chosenMeals.insert(meal);
}

bool MealSelector::isPastaMeal(const std::string& meal) {
    return (meal == "Pesto" || meal == "Spaghetti" || meal == "Tortellini");
}

bool MealSelector::canSelectPastaMeal(const std::string& meal) {
    if (isPastaMeal(meal)) {
        if (!pastaAllowed || mealCount >= 3) {
            return false; // Disallow selecting more pasta meals if one is already selected
        }

        for (const auto& selectedMeal : lastPastaSelections) {
            if (mealCount - selectedMeal.second < 3 && meal != selectedMeal.first) {
                return false; // Check conditions for pasta meal selection
            }
        }
    }
    return true;
}

void MealSelector::handleSelectedPastaMeal(const std::string& meal) {
    if (mealCount >= 4 || !pastaAllowed) {
        return; //Exit if already selected 4 meals or if pasta is not allowed
    }

    //Check if the pasta meal is allowed based on previous selections
    if (isPastaMeal(meal) && lastPastaSelections.find(meal) != lastPastaSelections.end()) {
        return; // Exit if this pasta meal was already chosen
    }

    // Ensure mutual exclusion among pasta meals
    for (const auto& pasta : {"Spaghetti", "Tortellini", "Pesto"}) {
        if (pasta != meal && lastPastaSelections.find(pasta) != lastPastaSelections.end()) {
            return; // Exit if another pasta meal was already chosen
        }
    }

    printAndAddMeal(meal);
    mealCount += (isPastaMeal(meal)) ? 2 : 1; // Pasta meals count as 2 meals

    if (isPastaMeal(meal)) {
        pastaAllowed = false; // Set pastaAllowed to false after selecting one pasta meal
        lastPastaSelections[meal] = mealCount;
    }
}

void MealSelector::handleRegularMeal(const std::string& meal) {
    if (!isPastaMeal(meal) && mealCount == 3) {
        pastaAllowed = false;
    }
    printAndAddMeal(meal);
    mealCount++;
}

mealSelector.h

#pragma once

#include <iostream>
#include <vector>
#include <random>
#include <unordered_set>
#include <unordered_map>

class MealSelector {
private:
    std::vector<std::string> meals;
    std::unordered_set<std::string> chosenMeals;
    std::unordered_map<std::string, int> lastPastaSelections; // Track last selection for each pasta meal
    int mealCount;
    bool pastaAllowed;

public:
    MealSelector(const std::vector<std::string>& initialMeals);

    void shuffleMeals();
    void selectMeals();

private:
    void printAndAddMeal(const std::string& meal);
    bool isPastaMeal(const std::string& meal);
    bool canSelectPastaMeal(const std::string& meal);

    void handleSelectedPastaMeal(const std::string& meal);
    void handleRegularMeal(const std::string& meal);
};

当我运行代码时,有时会输出如下内容: 饺子 意大利细面条 烤奶酪

这个: 土豆皮 午餐肉三明治 通心粉和奶酪 饺子

或者这个: 意大利细面条 饺子 香蒜沙司

我一生都无法弄清楚出了什么问题。这可能是一个脑屁,但请帮忙。

c++ class random conditional-statements
1个回答
0
投票

我建议将属性或属性转移到膳食上:

    class Meal
    {
        std::string    m_title;
        unsigned int   m_serves_count;  
        std::string    m_primary_ingredient;
      public:  
        Meal(const std::string& title) : m_title(title)
            { ; }  
        bool contains_ingredient(const std::string& ingredient_title) const  
            { return m_primary_ingredient == ingredient_title; }
        unsigned int get_serving_count() const 
            { return m_serves_count; }  
};

你可以拥有

std::vector<Meal> weekly_meals;
。 要查找所有包含面食的餐食:

const unsigned int meal_count = weekly_meals.size();  
for (unsigned int i = 0u; i < meal_count; ++i)
{
    if (weekly_meals[i].contains_ingredient("pasta"))
    {
        // Process the pasta meal
    }
}

上面的代码是完整的,但说明了将餐食属性移动到餐食中并在餐食容器中搜索包含适当属性的餐食的概念。

© www.soinside.com 2019 - 2024. All rights reserved.