im doing an assignment on c++ and im stuck on how i would add a new transaction to my work, with a user defined numShares, and pricePerShare.
i have a transaction struct which looks like this:
struct Transaction
{
string stockSymbol; // String containing the stock symbol, e.g. "AAPL"
string buyerName; // String containing the buyer's name e.g. "Mr Brown"
int buyerAccount; // Integer containing an eight digit account code
int numShares; // Integer containing the number of sold shares
int pricePerShare; // Integer containing the buy price per share
};
this is the buildTransaction class:
static Transaction* buildTransactions(int numTransactions)
{
int maxShareVolume = 100000;
int maxSharePrice = 1000;
Transaction *transactions = new Transaction[numTransactions];
for(int idx = 0; idx < numTransactions; idx++)
{
transactions[idx].stockSymbol = pickRandomStockSymbol();
std::string buyerName = pickRandomBuyer();
transactions[idx].buyerName = buyerName;
transactions[idx].buyerAccount = lookupBuyerAccount(buyerName);
transactions[idx].numShares = 1 + rand() % maxShareVolume;
transactions[idx].pricePerShare = 1 + rand() % maxSharePrice;
}
return transactions;
}
how would i use that to add data to the transactions array using this:
void Analyser::addTransactions(Transaction* transactions, int numTransactions)
i would assume from this that all i would really need to have as user input would be the amount of shares, and the price per share, but that the other information fills itself in automatically, from choosing from the arrays.
instead of using arrays, you should use vectors.. the buildTransactions would be written this way:
std::vector<Transaction> buildTransactions(int numTransactions)
{
int maxShareVolume = 100000;
int maxSharePrice = 1000;
std::vector<Transaction> transactions;
for(int idx = 0; idx < numTransactions; idx++)
{
Transaction t;
t.stockSymbol = pickRandomStockSymbol();
std::string buyerName = pickRandomBuyer();
t.buyerName = buyerName;
t.buyerAccount = lookupBuyerAccount(buyerName);
t.numShares = 1 + rand() % maxShareVolume;
t.pricePerShare = 1 + rand() % maxSharePrice;
transactions.push_back(t);
}
return transactions;
}
by editting the buildTransactions function, you can easily add more data by doing this to your addTransactions function:
void Analyser::addTransactions(std::vector<Transaction> &transactions, int numTransactions)
{
for(int idx = 0; idx < numTransactions; idx++)
{
Transaction t;
t.stockSymbol = pickRandomStockSymbol();
std::string buyerName = pickRandomBuyer();
t.buyerName = buyerName;
t.buyerAccount = lookupBuyerAccount(buyerName);
std::cout << "Enter number of shares for transaction: ";
std::cin >> t.numShares;
std::cout << "Enter price per share for transaction: ";
std::cin >> t.pricePerShare;
transactions.push_back(t);
}
}
hope it helps :)
you can get amount of shares, and the price per share as inputs in a loop in addTransactions() method like the following:
for(int idx = 0; idx < numTransactions; idx++)
{
transactions[idx].stockSymbol = pickRandomStockSymbol();
std::string buyerName = pickRandomBuyer();
transactions[idx].buyerName = buyerName;
transactions[idx].buyerAccount = lookupBuyerAccount(buyerName);
ctd::cout<<"Enter number of shares for transaction "<<idx+1<<std::endl;
std::cin>>transactions[idx].numShares;
ctd::cout<<"Enter price per share for transaction "<<idx+1<<std::endl;
std::cin>>transactions[idx].pricePerShare;
}
Related
Is there a way to loop this so I don't have to write it out 10 times?
Basically, I'm creating instances for a DVD class which each has different member values. It would be nice if I could make my file more readable. I've got this far.
for (int i=n; i<= 10; i++) {
for (int j=0; j<=9; j++) {
if (n == i) {
dvd[j].print();
}
}
}
but it's obviously wrong and I know why to. I just don't know if it's possible.
DVD dvd[10];
dvd[0].id = d[2];
dvd[0].name = d[3];
dvd[0].genre = d[4];
dvd[0].cast = d[5];
dvd[0].desc = d[6];
dvd[0].dateRent = d[7];
dvd[0].dateRet = d[8];
dvd[0].cost = d[9];
dvd[1].id = d[12];
dvd[1].name = d[13];
dvd[1].genre = d[14];
dvd[1].cast = d[15];
dvd[1].desc = d[16];
dvd[1].dateRent = d[17];
dvd[1].dateRet = d[18];
dvd[1].cost = d[19];
dvd[2].id = d[22];
dvd[2].name = d[23];
dvd[2].genre = d[24];
dvd[2].cast = d[25];
dvd[2].desc = d[26];
dvd[2].dateRent = d[27];
dvd[2].dateRet = d[28];
dvd[2].cost = d[29];
dvd[3].id = d[32];
dvd[3].name = d[33];
dvd[3].genre = d[34];
dvd[3].cast = d[35];
dvd[3].desc = d[36];
dvd[3].dateRent = d[37];
dvd[3].dateRet = d[38];
dvd[3].cost = d[39];
dvd[4].id = d[42];
dvd[4].name = d[43];
dvd[4].genre = d[44];
dvd[4].cast = d[45];
dvd[4].desc = d[46];
dvd[4].dateRent = d[47];
dvd[4].dateRet = d[48];
dvd[4].cost = d[49];
dvd[5].name = d[53];
dvd[5].id = d[52];
dvd[5].genre = d[54];
dvd[5].cast = d[55];
dvd[5].desc = d[56];
dvd[5].dateRent = d[57];
dvd[5].dateRet = d[58];
dvd[5].cost = d[59];
dvd[8].id = d[62];
dvd[8].name = d[63];
dvd[8].genre = d[64];
dvd[8].cast = d[65];
dvd[8].desc = d[66];
dvd[8].dateRent = d[67];
dvd[8].dateRet = d[68];
dvd[8].cost = d[69];
dvd[7].id = d[72];
dvd[7].name = d[73];
dvd[7].genre = d[74];
dvd[7].cast = d[75];
dvd[7].desc = d[76];
dvd[7].dateRent = d[77];
dvd[7].dateRet = d[78];
dvd[7].cost = d[79];
dvd[8].id = d[82];
dvd[8].name = d[83];
dvd[8].genre = d[84];
dvd[8].cast = d[85];
dvd[8].desc = d[86];
dvd[8].dateRent = d[87];
dvd[8].dateRet = d[88];
dvd[8].cost = d[89];
dvd[9].id = d[92];
dvd[9].name = d[93];
dvd[9].genre = d[94];
dvd[9].cast = d[95];
dvd[9].desc = d[96];
dvd[9].dateRent = d[97];
dvd[9].dateRet = d[98];
dvd[9].cost = d[99];
and
if (n == 1) {
dvd[0].print();
}
if (n == 2) {
dvd[1].print();
}
if (n == 3) {
dvd[2].print();
}
if (n == 4) {
dvd[3].print();
}
if (n == 5) {
dvd[4].print();
}
if (n == 6) {
dvd[5].print();
}
if (n == 7) {
dvd[6].print();
}
if (n == 8) {
dvd[7].print();
}
if (n == 9) {
dvd[8].print();
}
if (n == 10) {
dvd[9].print();
}
eglease's comment was spot on: You'll notice that the index you want to print is one smaller than your n (wherever that comes form), so you can simply use n-1 as an index to print. That is, I think, what you tried to achieve with your nested loop and did with your if-chain, but you were thinking too complicated: No loop is required! You could have spotted the connection between n and the array index when you wrote the if-chain: The index is always one smaller than the n. You can simply write that ;-).
void print dvd_number_n(int n) { dvd[n-1].print(); }
If you want to loop over all your DVDs you can loop from 0 to n-1, which is very common in C or C++ because it has zero-based arrays, that is, the first element is at index 0.
The idiomatic way to code that is a for loop starting at 0 and testing the loop variable for being truly smaller than the number of elements.
For an array with 3 DVDs array alements would be dvd[0], dvd[1], and dvd[2]. dvd[3] would be out-of-bounds, because there are only 3 elements in the array, not 4. Such boundary violations are one of the most common errors in C or C++ which do not check array indices (and typically can't do that at all because the array size is unknown at the site of use). The print loop for an array of 3 DVDs would be
for( int i=0; i<3; i++) { dvd[i].print(); }
The index i
starts with 0, execute loop (1)
is incremented to 1, smaller than 3, execute loop (2)
is incremented to 2, smaller than 3, execute loop (3)
is incremented to 3, equal to 3, loop condition is false, loop is left.
This gives us the 3 loop executions with the indices 0,1,2 as desired.
There is a lot of room for improvement: Give your class a constructor and use a vector, not an array. Here is an example that may give you an idea.
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
/// A simple data holder for DVD information with a constructor.
class DVD_T
{
std::string mTitle;
unsigned int mCost; // in cent
public:
DVD_T(std::string title, unsigned int cost): mTitle(title), mCost(cost) {}
void print(std::ostream &os)
{
os << "Title: \"" << mTitle
<< "\", cost: $" << mCost/100 << "." << std::setw(2) << std::setfill('0') << mCost%100;
}
};
std::vector<DVD_T> &initDVDs()
{
// This initialization of a static local variable will be run only once.
static std::vector<DVD_T> DVDs
{
// You'll probably want to obtain data from your data array d.
{"Title 1", 109},
{"Title 2", 99}
};
return DVDs;
}
int main()
{
// Get reference to initialized vector of DVDs
std::vector<DVD_T> &DVDs = initDVDs();
// Print them all. "Look mama, no index!"
for(auto dvd: DVDs)
{
dvd.print(std::cout);
std::cout << '\n';
}
}
Output:
Title: "Title 1", cost: $1.09
Title: "Title 2", cost: $0.99
I am trying to solve this question:
https://www.hackerearth.com/practice/algorithms/greedy/basics-of-greedy-algorithms/practice-problems/algorithm/minimum-cabs-0798cfa5/description/
I see a solution here but I don't quite understand it.
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1500;
int A[MAX];
int main(int argc, char* argv[])
{
if(argc == 2 or argc == 3) freopen(argv[1], "r", stdin);
if(argc == 3) freopen(argv[2], "w", stdout);
ios::sync_with_stdio(false);
int n, hh1, hh2, mm1, mm2, smins, emins, ans;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> hh1 >> mm1 >> hh2 >> mm2;
smins = hh1 * 60 + mm1;
emins = hh2 * 60 + mm2;
A[smins]++;
A[emins+1]--;
}
ans = A[0];
for (int i = 1; i < MAX; i++) {
A[i] += A[i-1];
ans = max(ans, A[i]);
}
cout << ans << endl;
return 0;
}
Could someone explain the algorithm to me?
The given solution works on maximum overlapping intervals.
The author wants to count the maximum number of intervals or ranges which overlap at any given point in the time.
Assume a time scale, which represents time:
Min time: 00:00 => represents 0 on the time scale
Max time: 23:59 => represents 1439 on the time scale
So, author used a constant MAX as 1500, thus making a time scale of [0, 1500], which satisfies our requirement.
Now, for each interval/ range we got from the input, author made use of prefix sum, thus adding 1 to every time unit in the range.
For eg: Suppose my range is 00:00 to 12:36, then I will add 1 to every index of array A from 0 to 756.
The maximum prefix sum denotes the minimum number of cabs required as 1 cab can be only be allocated to 1 person at any particular instance of time.
Hope this helps. Feel free to ask any doubts. Kindly mark answer correct if satisfies your doubt.
class TestClass
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
int arr[] = new int[24*60+1];
while(t!=0)
{
int st = sc.nextInt()*60+sc.nextInt();
int et = sc.nextInt()*60+sc.nextInt();
for(int i=st;i<=et;i++)
{
arr[i]++;
}
t--;
}
int max=0;
for(int i=0;i<arr.length;i++)
{
max=Math.max(max,arr[i]);
}
System.out.println(max);
}
}
I have a C++ assignment which I've been working on in the last 2 weeks. My knowledge is very limited, as I just started learning C++ and algorithms in February.
The assignment is:
N number of guests were invited to a party. We know all guests arrival and leave time. We want to know which guest met the LEAST amount of other guests. Two guests meet when guest1_arrivaltime <= guest2_leavetime and guest2_arrivaltime <= guest1_leavetime. If there are multiple guests who met the same amount of other guests, only one needs to be printed out.
Use: standard input (cin, cout) and greedy algorithm.
N (number of guests) can range from 1 to 1 000 000, the arrival and leave time values can be between 1 and 100 000
Run time limitation: 0.1 second
Memory limitation: 32 MB
I have a working code which seems to be okay to me, but when I upload it to the school's server I only get 27 marks out of 100. I need 50 marks to pass.
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
struct guestData
{
int guestIndex;
int time;
guestData(int guestIndex, int time)
{
this->guestIndex = guestIndex;
this->time = time;
}
guestData()
{
guestIndex = 0;
time = 0;
}
};
int n;
guestData * arrive;
guestData * leave;
set<int> guestsIn;
set<int> * metSet;
int minGuests;
int minIndex = 1;
bool operator<(const guestData & l, const guestData & r)
{
return l.time < r.time;
}
void read(int n)
{
arrive = new guestData[n];
leave = new guestData[n];
metSet = new set<int>[n];
minGuests = n;
for (int i = 0; i < n; ++i){
int arriveTime;
int leaveTime;
cin >> arriveTime >> leaveTime;
arrive[i] = guestData(i, arriveTime);
leave[i] = guestData(i, leaveTime);
}
}
void process()
{
sort(arrive, arrive+n);
sort(leave, leave+n);
int i = 0, j = 0;
while (i < n && j < n)
{
if (arrive[i].time <= leave[j].time)
{
int currentTime = arrive[i].time;
int in = arrive[i].guestIndex;
for (auto it = guestsIn.begin(); it != guestsIn.end(); ++it)
{
metSet[in].insert(*it);
metSet[*it].insert(in);
}
guestsIn.insert(in);
i++;
}
else
{
int currentTime = leave[j].time;
int out = leave[j].guestIndex;
guestsIn.erase(out);
j++;
}
}
}
void findMin(){
for (int i = 0; i < n; ++i)
{
if (metSet[i].size() < minGuests)
{
minGuests = metSet[i].size();
minIndex = i+1;
}
}
}
int main()
{
cin >> n;
read(n);
process();
findMin();
cout << minIndex << " " << minGuests;
return 0;
}
The problem: it works great on the example input, which is:
8
1 3
4 8
9 12
2 5
3 9
7 10
2 3
1 3
where 8 is the n (number of guests) and then 8 x the arrival(left row) and leave time(right row) for the guests.
The output for this example input is: 3 2 which is correct, because the 3rd guests met the least amount of other guests (2)
However, I get this error on my school's website when I upload my code: ERROR CODE 11 ILLEGAL MEMORY REFERENCE
You should free the memory at the end of the program. The grading system probably detects you are not doing that.
delete[] arrive;
delete[] leave;
delete[] metSet;
I am using OpenCV and I use cv::RNG to generate pick randomly a percent from the images in the list:
void chooseImages(const StringVector& imagesListIn, StringVector& imagesListPartOut)
{
imagesListPartOut.clear();
if (m_perecent == 1)
{
imagesListPartOut = imagesListIn;
}
else
{
// copy the imagesListIn for being able to remove the chosed images
int percent = static_cast<int>(m_perecent * imagesListIn.size() + .5);
cv::RNG randomChooser;
StringVector listCpy = imagesListIn;
int index;
int listSize = imagesListIn.size();
std::string name;
for (int i = 0; i < percent; i++)
{
index = randomChooser.next() % listSize;
std::cout << index << " ";
name = listCpy[index];
listCpy.erase(listCpy.begin() + index);
imagesListPartOut.push_back(name);
listSize = listCpy.size();
}
std::cout << std::endl;
}
}
My problem is that it always pick the same images; it always prints the same numbers (cv::RNG always generate the same numbers). How to make it generate different randomly umbers?
You need to seed a random number generator with a random starting state. See rng docs. Typically you use the computer's current time
I have a homework assignment which I feel I am close to getting right. The assignment is as follows:
Banks loan money to each other. In tough economic times, If a bank goes bankrupt it may not be able to pay back the loan. A bank's total assets is its current balance plus its loans to other banks. Figure 8.1 ( attached image ) is a diagram tat shows five banks. The banks' current balances are: 25, 125, 175, 75 and 181 million dollars, respectively. The directed edge from node 1 to node 2 indicates that bank 1 loans 40 mill to bank 2.
If a banks total asset is under a certain limit, the bank is considered unsafe. If a bank is unsafe, the money it borrowed cannot be returned to the lender and the lender cannot count the loan in its total assets. Consequently, the Lender may also be unsafe.
Write a program to find all unsafe banks. Your program reads the input as follows. It first reads two integers, n and limit, where n indicates the number of banks and limit is the minimum assets for keeping a bank safe. It then reads n lines that describe the information for n banks with id from 0 to n-1. The first number in the line is the bank's balance. The second number indicates the number of that borrowed money from the bank, and the rest are pairs of two numbers. Each pair describes a borrower. The first number is the banks id and the second number is how much it borrowed. Assume that the maximum number of banks is 100. For example, the input for the five banks is as follows ( the limit is 201)
5 201
25 2 1 100.5 4 320.5
125 2 2 40 3 85
175 2 0 125 3 75
75 1 0 125
181 1 2 125
The total assets of bank 3 is 75 plus 125 which is under 201 so the bank is unsafe. After bank 3 is unsafe the total assets of bank 1 becomes 125 + 40 and is now also unsafe. The output should be "Unsafe banks are 3 1"
This is my current solution to the problem. I can't figure out how to get it to find all the unsafe banks. Just the first one. I have it set to take static input for testing. I have the working user input code ready to go if I can just get it to work properly.
#include <iostream>
using namespace std;
int main()
{
const int SIZE = 100;
double balance[SIZE];
double loan[SIZE][SIZE];
int nobanks;
int limit;
int i = 0;
int j = 0;
int k = 0;
int noborrowers;
double assets[SIZE];
bool isSafe[SIZE];
bool newunsafefound = true;
cout << "Enter number of banks and the limit:" << endl;
// Set all of the data
nobanks = 5;
limit = 201;
balance[0] = 25.0;
balance[1] = 125.0;
balance[2] = 175.0;
balance[3] = 75.0;
balance[4] = 181.0;
loan[0][1] = 100.5;
loan[0][4] = 320.5;
loan[1][2] = 40.0;
loan[1][3] = 85.0;
loan[2][0] = 125.0;
loan[2][3] = 75.0;
loan[3][0] = 125.0;
loan[4][2] = 125.0;
// Set array to all true values
for(i = 0; i < nobanks; i++)
{
isSafe[i] = true ;
}
cout << "Unsafe banks are: ";
i=0;
while(isSafe[i] == true)
{
newunsafefound=false;
i=0;
do
{
assets[i] = balance[i]; //Set assets to balance
for (j = 0; j < nobanks; j++) // Check if a bank has loans and add them to assets
{
if (loan[i][j] >= 0)
assets[i] += loan[i][j];
}
if (assets[i] < limit) // Check to see if current bank meets limit
{
isSafe[i] = false; // Set bank to not safe if limit not met
newunsafefound = true;
cout << i << " " ; //Display the bank that is unsafe and a space for the next bank
k=0;
for (k = 0; k < nobanks; k++)
{
loan[i][k] = 0; //Set banks loans to 0 if unsafe.
k++;
}
}
i++;
} while(i < nobanks);
}
return (0);
}
What am I doing wrong?
You have to explicitly initialize the loan array, so the elements you aren't using don't have arbitrary values:
double loan[SIZE][SIZE] = {{0}};
Also loan[i][k] = 0; means that you are zeroing the loan the bank i has given to the bank k, but what you want is to zero any money that the bank i has borrowed to the bank k.
And there is a problem:
in the exit condition of your outer loop (it would only exit if the last bank (nobank-1) was unsafe),
in the handling of newunsafefound which doesn't do what the variable name suggests.
for (k = 0; k < nobanks; k++)
{
loan[i][k] = 0; //Set banks loans to 0 if unsafe.
k++;
}
That extra increment for k looks very suspicious ;)
// Astrid Giraldo
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
int n; // number of banks
double limit; // Minimum total assets for keeping a bank safe.
System.out.println("Enter number of banks: ");
n = input.nextInt();
System.out.println("Enter minimum total assets to be a safe bank: ");
limit = input.nextDouble();
double[][] borrowers = new double[n][n];
double[] balance = new double[n];
int numBorrowers;
for (int i = 0; i < borrowers.length; i++) {
System.out.println("Enter the bank's balance");
balance[i] = input.nextDouble();
System.out.println("Enter number of borrowers from this bank");
numBorrowers = input.nextInt();
for (int j = 0; j < numBorrowers; j++) {
System.out.println("Enter borrower bank id and the amount borrowed: ");
borrowers[i][input.nextInt()] = input.nextDouble();
}
}
markUnsafeBanks(borrowers,balance, limit);
displayUnsafeBanks(borrowers, balance, limit);
}
public static double analizeUnsafeBanks(double[][] borrowers, double[] balance, int bankId) {
double sum = balance[bankId];
for (int i = 0; i < borrowers.length; i++) {
sum += borrowers[bankId][i];
}
return sum;
}
public static void setLoanToZero(double[][] borrowers, double[] balance, int unsafeBankId, double limit) {
for (int i = 0; i < borrowers.length; i++) {
if (borrowers[i][unsafeBankId] > 0) {
borrowers[i][unsafeBankId] = 0;
if ( unsafeBankId > i && analizeUnsafeBanks(borrowers, balance, i) < limit) {
setLoanToZero(borrowers, balance, i, limit);
}
}
}
}
public static void markUnsafeBanks(double[][] borrowers, double[] balance, double limit) {
for (int i = 0; i < borrowers.length; i++) {
if (analizeUnsafeBanks(borrowers, balance, i) < limit) {
setLoanToZero(borrowers, balance, i, limit);
}
}
}
public static void displayUnsafeBanks(double[][] borrowers, double[] balance, double limit){
for (int i = 0; i < borrowers.length; i++) {
double assets = analizeUnsafeBanks(borrowers,balance,i);
if ( assets < limit) {
System.out.println("Bank " + i + " is unsafe. It assets are " + assets);
}
}
}