How to print the map like a template? - c++

Here is my code:
To understand the code I have to explain a little. First I am getting student and course data from user in different classes. Then in Schedule class I am trying to create a schedule for student. When user enter a valid student and course name I am inserting these datas to another map.
map< string,map<pair<string,int>,pair<string,Array> > > courseScList;
map<pair<string,int>,pair<string,Array> > matchMap;
matchMap map has these datas from another class:
course name,course hours,course day,available hours in this day
These 2 are mine maps and I am using these maps in this code:
void Schedule::studentSchedule() {
string c,s;
int courseNum;
list<string>::iterator studentLoc;
map< string,map<pair<string,int>,pair<string,Array> > >::iterator last;
map<pair<string,int>,pair<string,Array> >::iterator location;
map<pair<string,int>,pair<string ,Array> >::iterator match;
dummy1:
cout<<"Enter the student name"<<endl;
cin >> s;
wrongCourse:
cout<<"Enter the course names you want"<<endl;
cin>>c;
auto predicate = [&](auto& course) { return compareName(course, c); };
studentLoc = find(getStudentList().begin(),getStudentList().end(),s);
location = find_if(getMatchMap().begin(), getMatchMap().end(), predicate);
if(studentLoc != getStudentList().end() || location != getMatchMap().end())
{
getCourseScList().insert(make_pair(s,getMatchMap()));
}
else
{
cout<<"The course or student you wrote isn't available.Please enter existed courses!"<<endl;
goto wrongCourse;
}
cout<<"\n"<<endl;
char dummy;
cout<<"\nDo tou want to create a new schedule?Press y or n."<<endl;
cin>>dummy;
if(dummy == 'Y' || dummy == 'y')
goto dummy1;
else
{
location = last->second.begin();
for(last = getCourseScList().begin();last!=getCourseScList().end();++last)
{
cout<<last->first<<"\t"<<(location->first).first<<"\t"<<(location->second).first<<"\t";
for (const int element : location->second.second)
std::cout << element << " ";
cout<<endl;
++location;
}
}
I am trying to get student and course name from user and if student name and course name in the map I am inserting this to another map. However when I try to print these student,course,day and day hours data I can't see these in same line. I think the wrong code is this:
else
{
cout<<"The course or student you wrote isn't available.Please enter existed courses!"<<endl;
goto wrongCourse;
}
cout<<"\n"<<endl;
char dummy;
cout<<"\nDo tou want to create a new schedule?Press y or n."<<endl;
cin>>dummy;
if(dummy == 'Y' || dummy == 'y')
goto dummy1;
else
{
location = last->second.begin();
for(last = getCourseScList().begin();last!=getCourseScList().end();++last)
{
cout<<last->first<<"\t"<<(location->first).first<<"\t"<<(location->second).first<<"\t";
for (const int element : location->second.second)
std::cout << element << " ";
cout<<endl;
++location;
}
}
With this print loop i can't see the template like this;
Studentname1 -- > Coursename1 ----> Courseday1 -->Coursehours1
Studentname1 -- > Coursename2 ----> Courseday2 -->Coursehours1
Studentname2 -- > Coursename1 ----> Courseday1 -->Coursehours1
Studentname3 -- > Coursename2 ----> Courseday2 -->Coursehours
This is just an example what I want to do. How can I organize the code for it?

Related

Returning a vector from a function in order to print the contents

My program has a function named 'WordLadder' that uses BFS to make a path from one word in a dictionary to another. I was given a starter code that prints the number of nodes in the path, but I want to print the path itself. Currently, I have appended the words to a vector as they enter a queue but I am not able to return the vector as part of my 'WordLadder' function in order to print it in the main program.
I just want the program to print a path based on the two words I picked, i.e. "TOON - POON - POIN - POIE - PLIE - PLEE - PLEA", if the start word is "TOON" in the dictionary and the target word is "PLEA" in the dictionary.
I tried to declare the vector outside of the function and print it in main with this code, but I was unsuccessful.
void print(std::vector < int >
const & transformation) {
std::cout << "The vector elements are : ";
for (int i = 0; i < transformation.size(); i++)
std::cout << transformation.at(i) << ' ';
}
I have attempted to return the vector inside of the function, but I receive this error
error: no viable conversion
from returned value of type
'vector<std::__cxx11::string>' (aka
'vector<basic_string<char> >') to
function return type 'int'
return transformation;
Here is my code. Any help would be appreciated, as I am new to C++.
// To check if strings differ by exactly one character
bool nextWord(string & a, string & b) {
int count = 0; // counts how many differences there
int n = a.length();
// Iterator that loops through all characters and returns false if there is more than one different letter
for (int i = 0; i < n; i++) {
if (a[i] != b[i]) {
count++;
}
if (count > 1) {
return false;
}
}
return count == 1 ? true : false;
}
// A queue item to store the words
struct QItem {
string word;
};
// Returns length of shortest chain to reach 'target' from 'start' using minimum number of adjacent moves. D is dictionary
int wordLadder(string & start, string & target, set < string > & ew) {
//Create vector to store path in a
vector < string > transformation;
// Create a queue for BFS and insert 'start' as source vertex
queue < QItem > Q;
QItem item = {
start
};
Q.push(item);
// While queue is not empty
while (!Q.empty()) {
// Take the front word
QItem curr = Q.front();
transformation.push_back(Q.front().word);
Q.pop();
// Go through all words of dictionary
for (set < string > ::iterator it = ew.begin(); it != ew.end(); it++) {
// Proccess the next word according to BFS
string temp = * it;
if (nextWord(curr.word, temp)) {
// Add this word to queue from the dictionary
item.word = temp;
Q.push(item);
// Pop from dictionary so that this word is not repeated
ew.erase(temp);
// If we reached target
if (temp == target) {
return trasformation;
}
}
}
}
return 0;
}
// Driver program
int main() {
string start;
string target;
// make dictionary
std::ifstream file("english-words.txt");
set < string > ew;
copy(istream_iterator < string > (file),
istream_iterator < string > (),
inserter(ew, ew.end()));
cout << endl;
cout << "Enter Start Word" << endl;
cin >> start;
cout << "Enter Target Word" << endl;
cin >> target;
cout << wordLadder(start, target, ew);
return 0;
}
There are multiple problems.
You were on the right track when you said "I tried to declare the vector outside of the function and print it in main..."
So, change wordLadder to take the vector by reference.
int wordLadder(vector<string> &transformation, string & start, string & target, set < string > & ew)
Then declare it in main and pass it to wordLadder
vector<string> t;
wordLadder(t, start, target, ew);
print(t);
You will have to also change print to take a vector of the right type, ie. string and not int
void print(std::vector < string > &transformation)

c++ retrieving object from tree

I am working on a project in which I have an account class that stores balances for different funds. Each account object has 10 funds in which they start at 0 and transactions such as deposit, withdraw, and tranfer can be made. I need to store these accounts in a binary search tree as they are added and I am having issues with my retrieve function. The code is the following:
bool Retrieve(const int & acctNum, Account* acctPtr)
{
if (Search(root, acctPtr, acctNum))
return true;
else
return false;
}
bool Search(Node* temp, Account* acctPtr, int acctNum)
{
if (temp == NULL) {
return false;
}
else if (temp->pAcct->getAcct() == acctNum)
{
acctPtr = temp->pAcct;
return true;
}
else if (acctNum <= temp->pAcct->getAcct())
{
return Search(temp->left, acctPtr, acctNum);
}
else
{
return Search(temp->right, acctPtr, acctNum);
}
}
The problem I am running into is when I deposit into the account and then later retrieve and try to withdraw, it is not giving me the same account. Rather, it just tries to withdraw from an account with all 0 balances. My intention is for the acctPtr to point to the correct account to do the transfer/withdraw/deposit too. Here is how I am calling the retrieve from a different class that is used for completing the transactions:
if (transType == "D")
{
iss >> acctNum >> amt;
fund = parseCommand(acctNum);
acctNum = acctNum.substr(0, acctNum.length() - 1);
Account * d = new Account("name", stoi(acctNum));
if (bST->Retrieve(stoi(acctNum), d))
{
d->deposit(fund, amt);
cout << d->getFundBalance(fund) << endl; //for checking, will remove
}
}
else if (transType == "W")
{
iss >> acctNum >> amt;
fund = parseCommand(acctNum);
acctNum = acctNum.substr(0, acctNum.length() - 1);
Account * wD = new Account("name", stoi(acctNum));
if (bST->Retrieve(stoi(acctNum), wD))
{
wD->withdraw(fund, amt);
cout << wD->getFundBalance(fund) << endl; //for checking, will remove
}
}
The if statements above are just checking the type of transaction at the given time.
In your Search function, you use the argument acctPtr as an output (you assigned a new value to it).
But your pointer is not an output argument.
You should use Account** or Account*&.
And you will have to use the Retrieve method like this :
Account* d = NULL;
if(bST->Retrieve(stoi(acctNum),&d /* or just d if Account*& */))
{ ... }
If you use the Account** version, don't forget to assign the pointer with
*acctPtr = temp->pAcct;

if statement is executing,else-if statements are not in java

import javax.swing.JOptionPane;
public class sam{
public static void main(String[]args){
String a;
String b;
int c;
sam s1 = new sam();
a=s1.getInfo();
c=s1.getBalance();
b=s1.getMenu(a,c);
}
//menu method starts here
public String getMenu (String c, Integer d) {
String[] a;
String[] choices = { "Account Balance", "Deposit", "Withdraw", "User Account", "Exit options"};
String input = (String) JOptionPane.showInputDialog(null, "What would you like to do?",
"ATM menu", JOptionPane.QUESTION_MESSAGE, null,choices,choices[0]);
if ((choices[0] == choices[0])){
JOptionPane.showMessageDialog(null,"Your Account Balance is: "+d,"ATM machine",JOptionPane.INFORMATION_MESSAGE);}
//the if statement is executing properly
else if ((choices[1] == choices[1])){
String in=JOptionPane.showInputDialog("Deposit: ");
int deposit=Integer.parseInt(in);
int add=d+deposit;
JOptionPane.showMessageDialog(null,"Your Current Balance: "+add,"ATM machine",JOptionPane.INFORMATION_MESSAGE);}
//but when I chose account balance it displays the if statement not the else-if one
else if ((choices[2] == choices[2])){
String in=JOptionPane.showInputDialog("Withdraw: ");
int withdraw=Integer.parseInt(in);
int sub=d+withdraw;
JOptionPane.showMessageDialog(null,"Your Current Balance: "+sub,"ATM machine",JOptionPane.INFORMATION_MESSAGE);}
else if ((choices[3] == choices[3])){
JOptionPane.showMessageDialog(null," "+c,"ATM machine",JOptionPane.INFORMATION_MESSAGE);}
else if ((choices[4] == choices[4])){
JOptionPane.showMessageDialog(null,"The program will be terminated in a few seconds","ATM machine",JOptionPane.INFORMATION_MESSAGE);
}
return input;
}
//I'm quite new to programming, I rushed coded it for finals.
All of your if statements will evaluate to true. I think your intentions were to compare String c with each of the Strings in the choices array.
When comparing Strings always use .equals() not ==.
Example:
if (c.equals(choices[0])) {
// code
} else if (c.equals(choices[1])) {
//code
} else if (c.equals(choices[2])) {
// code
}

user defined variables on the heap getting destroyed in while loop

I an odd problem that i cant understand if someone could point me in the right direction it would be greatly appreciated.I create my own linked list variables on the heap but when i go to add another variable to it they all get destroyed and i dont know why.
in my main i set up my variables like this
main.cpp
Book* temp;
temp = bookSetUp();
this goes to a different cpp called functions which sets up the objects like this:
functions.cpp
Book* bookSetUp()
{
//The items that populate the list
Book* a= new Book("A Tale of Two Cities", "Charles Dickens", "1", true);
Book* b= new Book("Lord of the rings", "J.R.R Tolkein", "2", true);
Book* c= new Book("Le Petit Prince", "Antoine de Saint-Exupéry", "3", true);
Book* d= new Book("And Then There Were None", "Agatha Christie", "4", true);
Book* e= new Book("Dream of the Red Chamber","Cao Xueqin","5", true);
Book* f= new Book("The Hobbit","J.R.R Tolkein","6", true);
//sets up the pointers between books
a->setPrev(NULL);
a->setNext(b);
b->setPrev(a);
b->setNext(c);
c->setPrev(b);
c->setNext(d);
d->setPrev(c);
d->setNext(e);
e->setPrev(d);
e->setNext(f);
f->setPrev(e);
f->setNext(NULL);
//sets up a temp pointer to a
Book* temp = a;
//returns the temp pointer to a
return temp;
}
this works perfectly but later on when i go to add to the list again in the main using:
main.cpp
else if(checkRegUser(username, password, regUserList) == true)
{
int choice = 99;
cout << "Welcome Registered user: "<< username << endl;
while(choice != 0)
{
//this is so the print will start everytime as if you run it once print will be at NULL thereafter
Book* print = temp;
choice = options();
if(choice == 1)
{
while(print!=NULL)
{
cout<<"Name: "<<print->getName()<<endl<<"Author: "<<print->getAuthor()<<endl<<"ISBN: "<<print->getISBN()<<endl<<"Availability: "<<print->getAvail()<<endl;
cout<<endl;
print = print->getNext();
}
print = temp;
}
if(choice == 2)
{
search(temp);
}
if(choice == 3)
{
takeOut(temp);
}
if(choice == 4)
{
returnBack(temp);
}
if(choice == 5)
{
append(temp);
}
if(choice == 6)
{
cout<<"Sorry you have the privilege needed to use this function."<<endl;
}
if(choice == 7)
{
choice = 0;
}
}
}
My user defined variables get destroyed. I debugged and they just disappeared i am not sure why!
Just in-case its needed here is my add() function because I feel It could be me missing something small or just making a disastrous mistake. My add function is in the functions.cpp and I know all the links are working as I have everything else running apart from this
functions.cpp
Book* append(Book* tempParam)
{
string title;
string author;
string isbn;
bool avail;
cout<<"What is the book called?"<<endl;
cin.clear();
cin.ignore();
getline(cin, title);
cout<<"Who is the author?"<<endl;
cin.clear();
cin.ignore();
getline(cin, author);
cout<<"What is the ISBN to be?"<<endl;
cin>>isbn;
Book* temp = new Book(title, author, isbn, true);
Book* list = tempParam;int count;
while(list!=NULL)
{
if(list->getNext()==NULL&&list->getName()!=title)
{
list->setNext(temp);
temp->setNext(NULL);
temp->setPrev(list);
cout<<"Your book has been added"<<endl;
cout<<temp->getName()<<temp->getAuthor()<<endl;
}
list = list->getNext();
}
tempParam = list;
return tempParam;
}
My user defined classes are working perfectly its just when I go to add that my list gets destroyed any ideas??
*I think the error is found in this section of the code:
list->setNext(temp);
You are "losing" the books because you didn't save them before you change list->next.*
The answer is incorrect because the conditional statement makes sure that it is the last element of the list. Sorry!

C++ Passing map from object

I am building a simple program to 'learn as I go', this program takes a couple of text files and processors them, each line of the first text file is information about a person, and for each line an Object (of type Student (see below)) is created and added to a vector.
Within the Student objects is a map that stores that students marks.
I have a function within the student class that returns the map when called (or at least thats what im trying to do).
Currently this function is:
marksType Student::printMarks(){
return marks;
}
(Where marksType = std::map<string, float>)
and marks is the map of type marksType.
Then in my main function I have:
Student a = *qw;
studmarks = a.printMarks();
for (std::map<string, float>::iterator iter = studmarks.begin(); iter != studmarks.end(); iter++){
cout << "TEST" << endl;
}
Where qw is a pointer to a student object and studmarks is of type map<string, float>
The issue is that the cout doesn't get called so the iterator seems to skip (but the student object does have items in the marks map).
Heres the complete Student class
#include "Student.h"
using namespace std;
typedef std::map<string, float> marksType;
Student::Student(const string &name, int regNo) : Person(name){
marksType marks;
this->regNo = regNo;
}
int Student::getRegNo() const{
return regNo;
}
void Student::addMark(const string& module, float mark){
pair<marksType::iterator,bool> check;
check = marks.insert (pair<string,float>(module,mark));
if (check.second==false){
marks[module]=mark;
}
}
float Student::getMark(const string &module) const throw (NoMarkException){
if (marks.find(module) != marks.end()){
return marks.find(module)->second;
}
else throw NoMarkException();
}
float Student::getAverageMark() const throw (NoMarkException){
if (!marks.empty()){
float avgmark = 0;
for (marksType::const_iterator avgit=marks.begin(); avgit!=marks.end(); ++avgit){
avgmark = avgmark + avgit->second;
}
avgmark = avgmark/marks.size();
return avgmark;
}
else throw NoMarkException();
}
marksType Student::printMarks(){
return marks;
}
Oh and below is the part of the main function that adds marks to the students,
for (vector<Student>::iterator it = students.begin(); it != students.end(); ++it){
Student b = *it;
if (regno == b.getRegNo()){
found = true;
b.addMark(module, mark);
}
}
I know this works because when I use the getMark function it does work.
You are "adding marks" to copies of the students stored in vector students. Each of these copies only lives during one iteration of the loop and the result is that you are not modifying the vector's elements at all:
for (vector<Student>::iterator it = students.begin(); it != students.end(); ++it){
Student b = *it; // b IS A COPY
if (regno == b.getRegNo()){
found = true;
b.addMark(module, mark); // modify local copy of Student
}
}
To add them to the elements of the vector, use
for (vector<Student>::iterator it = students.begin(); it != students.end(); ++it){
if (regno == it->getRegNo()){
found = true;
it->addMark(module, mark);
}
}