I have a recursive function. And I want to optimize it as less as 10 sec. Higher use of Memory is not an issue.
Currently, it takes around 85 sec on Linux and three times more on Mac.
I could not understand in what way I can proceed?
Here is code:
using namespace std;
double get_wall_time(){
struct timeval time;
if (gettimeofday(&time,NULL)){
// Handle error
return 0;
}
return (double)time.tv_sec + (double)time.tv_usec * .000001;
}
int fun(long long n) {
if (n < 0) {
cout << "Please enter valid number";
return 0;
}
else if (n == 0 || n == 1)
return 1;
else if (n % 2 == 0)
return fun(n / 2);
else if (n % 2 == 1)
return fun(n / 2) + fun(n / 2 - 1);
else
return 0;
}
int main() {
double begin = get_wall_time();
cout << fun(123456789012345678) << std::endl;
double end = get_wall_time();
cout << "Time elapsed : " << double(end - begin);
return 0;
}
EDIT:
If n is even, return f(n/2)
If n is odd, return f(n/2)+f(n/2-1)
I would memoize the results using a std::map, like so:
std::map<long long, int>fun_results;
int fun(long long n) {
try {
return fun_results.at(n);
} catch(const std::out_of_range&) {
if (n < 0) {
cout << "Please enter valid number";
return 0;
}
else if (n == 0 || n == 1)
return fun_results[n] = 1;
else if (n % 2 == 0)
return fun_results[n] = fun(n / 2);
else if (n % 2 == 1)
return fun_results[n] = fun(n / 2) + fun(n / 2 - 1);
else
return 0;
}
}
Result:
1332403
Time elapsed : 0.000710011
Related
My goal is to figure out whether each element of an array is a prime or not.
Example:
Input: int A[5]={1,2,3,4,5}
Output: bool P[5]={0,1,1,0,1}
The problem is the array size is up to 10^6. I tried the most efficient prime-checking algorithm
(code: http://cpp.sh/9ewxa) but just the "cin" and "prime_checking" take really long time. How should I solve this problem, Thanks.
Your "most efficient" prime test is actually horribly inefficient. Something like the Miller-Rabin primality test is much faster on a one by one basis. If your input are below 4.3 billion (i.e. uint32_t) then you only need to do 3 tests: a = 2, 7, and 61. For numbers in the uint64_t range it's 12 tests.
If you have a large array of integers then computing all primes up to some maximum might be faster than repeated tests. See Sieve of Eratosthenes for a good way to compute all primes fast. But it's impractical if your input numbers can be larger than 4 billion due to the memory required.
Here is some code that computes a Sieve up to UINT32_MAX+1 and then checks Miller-Rabin has the same results as the sieve: https://gist.github.com/mrvn/137fb0c8a5c78dbf92108b696ff82d92
#include <iostream>
#include <cstdint>
#include <array>
#include <ranges>
#include <cassert>
#include <bitset>
uint32_t pow_n(uint32_t a, uint32_t d, uint32_t n) {
if (d == 0) return 1;
if (d == 1) return a;
uint32_t t = pow_n(a, d / 2, n);
t = ((uint64_t)t * t) % n;
if (d % 2 == 0) {
return t;
} else {
return ((uint64_t)t * a) % n;
}
};
bool test(uint32_t n, unsigned s, uint32_t d, uint32_t a) {
//std::cout << "test(n = " << n << ", s = " << s << ", d = " << d << ", a = " << a << ")\n";
uint32_t x = pow_n(a ,d ,n);
//std::cout << " x = " << x << std::endl;
if (x == 1 || x == n - 1) return true;
for (unsigned i = 1; i < s; ++i) {
x = ((uint64_t)x * x) % n;
if (x == n - 1) return true;
}
return false;
}
bool is_prime(uint32_t n) {
static const std::array witnesses{2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u, 29u, 31u, 37u};
static const std::array bounds{
2'047llu, 1'373'653llu, 25'326'001llu, 3'215'031'751llu,
2'152'302'898'747llu, 3'474'749'660'383llu,
341'550'071'728'321llu, 341'550'071'728'321llu /* no bounds for 19 */,
3'825'123'056'546'413'051llu,
3'825'123'056'546'413'051llu /* no bound for 29 */,
3'825'123'056'546'413'051llu /* no bound for 31 */,
(unsigned long long)UINT64_MAX /* off by a bit but it's the last bounds */,
};
static_assert(witnesses.size() == bounds.size());
if (n == 2) return true; // 2 is prime
if (n % 2 == 0) return false; // other even numbers are not
if (n <= witnesses.back()) { // I know the first few primes
return (std::ranges::find(witnesses, n) != std::end(witnesses));
}
// write n = 2^s * d + 1 with d odd
unsigned s = 0;
uint32_t d = n - 1;
while (d % 2 == 0) {
++s;
d /= 2;
}
// test widtnesses until the bounds say it's a sure thing
auto it = bounds.cbegin();
for (auto a : witnesses) {
//std::cout << a << " ";
if (!test(n, s, d, a)) return false;
if (n < *it++) return true;
}
return true;
}
template<std::size_t N>
auto composite() {
std::bitset<N / 2 + 1> is_composite;
for (uint32_t i = 3; (uint64_t)i * i < N; i += 2) {
if (is_composite[i / 2]) continue;
for (uint64_t j = i * i; j < N; j += 2 * i) is_composite[j / 2] = true;
}
return is_composite;
}
bool slow_prime(uint32_t n) {
static const auto is_composite = composite<UINT32_MAX + 1llu>();
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
return !is_composite.test(n / 2);
}
int main() {
/*
std::cout << "2047: ";
bool fast = is_prime(2047);
bool slow = slow_prime(2047);
std::cout << (fast ? "fast prime" : "");
std::cout << (slow ? "slow prime" : "");
std::cout << std::endl;
*/
//std::cout << "2: prime\n";
for (uint64_t i = 0; i <= UINT32_MAX; ++i) {
if (i % 1000000 == 1) { std::cout << "\r" << i << " "; std::cout.flush(); }
bool fast = is_prime(i);
bool slow = slow_prime(i);
if (fast != slow) std::cout << i << std::endl;
assert(fast == slow);
//std::cout << i << ": " << (is_prime(i) ? "prime" : "") << std::endl;
}
}
The sieve takes ~15s to compute and uses 256MB of memory, verifying Miller-Rabin takes ~12m45s or 765 times slower than the sieve. Which tells me that if you are testing more than 85 million 32bit numbers for primes then just compute them all with a sieve. Since the sieve is O(n^2) it only gets better if your maximum input is smaller.
I have encountered the minimum coin change problem on CodeChef and CodeForces. On both sites I have submitted my implementation using DP. This implementation given TLE error on both sites.
Unfortunately, I cannot find any other implementation of this problem.
I am linking the problems -
CodeChef - https://www.codechef.com/problems/FLOW005
CodeForces - https://codeforces.com/problemset/problem/996/A
Here is my code(CodeChef implementation) -
int main() {
int T{};
std::cin >> T;
for (int i = 1; i <= T; ++i) {
int N{};
std::cin >> N;
std::vector <int> arr(N + 1);
for (int i = 0; i < N + 1; ++i) {
arr[i] = minCoins(i, arr);
}
std::cout << arr[N] << std::endl;
}
return 0;
}
The minCoins Function -
int minCoins(int x, std::vector <int> arr) {
if (x == 0)
return 0;
else if (x == 1 || x == 2 || x == 5 || x == 10 || x == 50 || x == 100)
return 1;
int min{ 1 + arr[x - 1]};
if (x > 100)
min = std::min(min, l + arr[x - 100]);
if (x > 50)
min = std::min(min, 1 + arr[x - 50]);
if (x > 10)
min = std::min(min, 1 + arr[x - 10]);
if (x > 5)
min = std::min(min, 1 + arr[x - 5]);
if (x > 2)
min = std::min(min, 1 + arr[x - 2]);
if (x > 1)
min = std::min(min, 1 + arr[x - 1]);
return min;
}
There is no problem of integer overflow as I chose int data type after reading the constraints.
Also, if anyone would like to suggest how I can remove the if ladder and replace it with something simpler, I would appreciate the help. Also, thank you for taking the time to read my question :)
#include <iostream>
int main() {
int tests;
std::cin >> tests;
int value;
while (tests--) {
int coinCount = 0;
std::cin >> value;
while (value > 0) {
if (value >= 100) {
coinCount += (value / 100);
value %= 100;
} else if (value >= 50) {
coinCount += (value / 50);
value %= 50;
} else if (value >= 10) {
coinCount += (value / 10);
value %= 10;
} else if (value >= 5) {
coinCount += (value / 5);
value %= 5;
} else if (value >= 2) {
coinCount += (value / 2);
value %= 2;
} else if (value >= 1) {
coinCount += (value / 1);
value = 0;
}
}
std::cout << coinCount << '\n';
}
}
Tested on CodeChef and passed with execution time of 0.00. The currency systems shown in the problems are designed in such a way that the greedy choice is the correct choice. This holds true for very nearly if not all existing currency systems.
If you require proof, http://www.cs.toronto.edu/~denisp/csc373/docs/greedy-coin-change.pdf
I'm trying to implement the Bulls & Cows game and I have a logic problem. I am explicitly checking if each digit is either equal to a digit in the corresponding index (bulls) or at other indexes (cows). The value that I check with (4321) should yield "0 bulls and 4 cows" but it instead gives me "0 bulls and 3 cows.
Here is my code (and I apologize for the code repetition. I am also wondering if anyone has recommendations to make this code smaller):
#include <iostream>
#include <vector>
using namespace std;
int main() {
int guessValue = 1234;
int guess;
int bulls = 0;
int cows = 0;
cout << "Enter a 4 digit guess: ";
cin >> guess;
int firstValue = (guess % 10000) / 1000;
int secondValue = (guess % 1000) / 100;
int thirdValue = (guess % 100) / 10;
int fourthValue = guess % 10;
if (firstValue == ((guessValue % 10000) / 1000)) {bulls += 1;}
else if(firstValue == ((guessValue % 1000) / 100) ||
firstValue == ((guessValue % 100) / 10) ||
firstValue == (guess % 10))
{cows += 1;}
if (secondValue == ((guessValue % 1000) / 100)) {bulls += 1;}
else if (secondValue == ((guessValue % 10000) / 1000) ||
secondValue == ((guessValue % 100) / 10) ||
secondValue == (guess % 10))
{cows += 1;}
if (thirdValue == ((guessValue % 100) / 10)) {bulls += 1;}
else if (thirdValue == ((guessValue % 10000) / 1000) ||
thirdValue == ((guessValue % 1000) / 100) ||
thirdValue == (guess % 10))
{cows += 1;}
if (fourthValue == (guessValue % 10)) {bulls += 1;}
else if (fourthValue == ((guessValue % 10000) / 1000) ||
fourthValue == ((guessValue % 1000) / 100) ||
fourthValue == (guessValue % 100) / 10)
{cows += 1;}
cout << bulls << " bulls and " << cows << " cows" << endl;
}
I am also wondering if anyone has recommendations to make this code smaller
First of all use std::vector to keep separate digits:
std::vector<int> split( int v )
{
std::vector<int> r;
while( v ) {
r.push_back( v % 10 );
v /= 10;
}
return r;
}
Second, use standard algo std::count_if:
auto bulls = std::count_if( guessv.begin(), guessv.end(),
[it = targetv.begin()]( int i ) mutable
{ return i == *it++; } );
auto cows = std::count_if( guessv.begin(), guessv.end(),
[s = std::set<int>{ targetv.begin(), targetv.end() }]( int i )
{ return s.count( i ); } );
second one is actually counts cows and bulls, so it needs to be adjusted:
cows -= bulls;
live example
2 concepts that absolutely you need to master: loops and functions. First create some helpful functions.
These are the functions you could built your program upon:
int get_digit(int number, int order)
with example test cases:
get_digit(7895, 0) == 5
get_digit(7895, 1) == 9
get_digit(7895, 2) == 8
get_digit(7895, 3) == 7
then:
bool has_digit(int number, int digit)
with example test cases:
has_digit(7895, 1) == false
has_digit(7895, 8) == true
has_digit(7895, 5) == true
has_digit(7895, 0) == false
has_digit(7000, 0) == true
then:
bool matches_digit(int a, int b, int order)
with test cases:
matches_digit(1239, 4269, 0) == true
matches_digit(1239, 4269, 1) == false
matches_digit(1239, 4269, 2) == true
matches_digit(1239, 4269, 2) == false
and finally:
int get_cow(int a, int b)
int get_bull(int a, int b)
int main()
This is a top-down design, bottom-up implementation approach. First you think of the big picture and figure out what small pieces you need (functions) and then start implementing from the smallest most independent functions and step by step combine then into higher functions until you reach main.
This is my solution and it works. Basically I had to create a function to extract each digit and store them into a vector that can be applied to both the model and the guess. Then I used the find() method of the <algorithm> library to see if the digits exist in the guess vector and if yes, at which position compared to the model vector. Same position equals 1 bull and different position equals 1 cow. I am going to add more to this program, such as generating the model randomly and looping the program after each round so the user doesn't have to restart the game.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> getDigits(int modelValue) {
vector<int> vectorValue;
int extractedDigit = 0;
int modulant = 10000;
int divisor = 1000;
for (int i = 0; i < 4; i++) {
extractedDigit = (modelValue % modulant) / divisor;
vectorValue.push_back(extractedDigit);
modulant /= 10;
divisor /= 10;
}return vectorValue;
}
int main() {
int model = 1234;
int guess = 0000;
int bulls = 0;
int cows = 0;
int counter = 1;
cout << "Enter a value to guess: ";
cin >> guess;
vector<int> modelVector = getDigits(model);
vector<int> guessVector = getDigits(guess);
for (int i = 0; i < 4; i++) {
if (find(modelVector.begin(), modelVector.end(), guessVector[i]) != modelVector.end()) {
if (modelVector[i] == guessVector[i]) {bulls += 1;}
else { cows += 1; }
}
}cout << "There are " << bulls << " bulls and " << cows << " cows"<< endl;
}
I'm afraid this is a bit of a long code. I'm programming a parallel, recursive, task-based version of Euler's partition formula with Intel TBB and C++, and I don't think there's much problem with this program's logic, but I have a feeling the variables are being accessed wrongly and I might have declared them in the wrong place or something. I say this because inputting a number n should always give the same result, and it does below n = 11, but above that it gives different answers. Even stranger, adding lines of output to try and troubleshoot the program results in slightly more accurate answers (as if somehow padding the time each part of the calculation takes helps it). I have no idea how to avoid this problem or which variable exactly is causing it as the answer is usually fairly close, it's not just a random number. So this is a bit of a tricky one, I apologise, but if someone could help me I would so damn thankful, I've spent a number of hours on this problem.
Here's the parallel task:
class ParallelFormula : public task {
public:
int n;
int* pTot;
//Task constructor
ParallelFormula(int n_, int* pTot_) : n(n_), pTot(pTot_) {}
//Task definition
task* execute() {
//Iterating for formula to work
for (int k = 1; k > 0; k++) {
//Add fixed values to pTot for any case where 2 >= n >= 0
switch (n) {
case 0:
if (k % 2 != 0)
*pTot += 1;
else
*pTot -= 1;
return NULL;
case 1:
if (k % 2 != 0)
*pTot += 1;
else
*pTot -= 1;
return NULL;
case 2:
if (k % 2 != 0)
*pTot += 2;
else
*pTot -= 2;
return NULL;
}
//Calculate p numbers using section of Euler's formula (relies on iteration number)
p1 = (k*((3 * k) - 1)) / 2;
p2 = (k*((3 * k) + 1)) / 2;
if (n >= p2) {
//If n is more than p2, must call recursive tasks to break down problem to smaller n's, and adds result to total result pTot (i.e. p(n))
int x = 0;
int y = 0;
ParallelFormula& a = *new(allocate_child()) ParallelFormula(n - p1, &x);
ParallelFormula& b = *new(allocate_child()) ParallelFormula(n - p2, &y);
//Set ref_count to two children plus one for the wait
set_ref_count(3);
//Start b running
spawn(b);
//Start a running and wait for all children (a and b)
spawn_and_wait_for_all(a);
//Sum the total
if (k % 2 != 0)
*pTot += (x + y);
else
*pTot -= (x + y);
}
else if (n >= p1) {
//If n is more than p1, problem is small and therefore need not be parallelised, result added to pTot
if (k % 2 != 0)
*pTot += serialLoop(n - p1);
else
*pTot -= serialLoop(n - p1);
return NULL;
}
else
return NULL;
}
}
};
The method that calls the parallel task:
int parallelLoop(int n) {
int pTot = 0;
ParallelFormula& a = *new(task::allocate_root()) ParallelFormula(n, &pTot);
task::spawn_root_and_wait(a);
return pTot;
}
In case you want to look at the full code for all the context:
// Assignment2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream"
#include "tbb/task_scheduler_init.h"
#include "tbb/parallel_reduce.h"
#include "tbb/partitioner.h"
#include "tbb/blocked_range.h"
#include "tbb/tick_count.h"
#include "math.h"
using namespace tbb;
using namespace std;
int p, p1, p2;
int serialLoop(int n);
int n;
int m;
int serialFormula(int pTemp) {
switch (pTemp) {
case 0:
return 1;
case 1:
return 1;
case 2:
return 2;
}
//If p is any other value it is less than 0 and therefore has nothing to calculate - the current calculation is complete
return 0;
}
int serialLoop(int n) {
int pTot = 0;
for (int k = 1; k > 0; k++) {
//Checking whether k is even or odd to determine if adding or substracting value of p(x) to make p(n)
if (n == 0)
return pTot += 1;
else if (k % 2 != 0) {
//Calculate p number using section of Euler's formula
p = n - ((k*((3 * k) - 1)) / 2);
//If p is more than 2, must call recursive function to break down problem to smaller n's, and adds result to total result P (i.e. p(n))
if (p > 2) {
pTot += serialLoop(p);
}
else if (p >= 0) {
pTot += serialFormula(p);
}
else return pTot;
p = n - ((k*((3 * k) + 1)) / 2);
if (p > 2) {
pTot += serialLoop(p);
}
else if (p >= 0) {
pTot += serialFormula(p);
}
else return pTot;
}
else {
p = n - ((k*((3 * k) - 1)) / 2);
if (p > 2) {
pTot -= serialLoop(p);
}
else if (p >= 0) {
pTot -= serialFormula(p);
}
else return pTot;
p = n - ((k*((3 * k) + 1)) / 2);
if (p > 2) {
pTot -= serialLoop(p);
}
else if (p >= 0) {
pTot -= serialFormula(p);
}
else return pTot;
}
}
}
class ParallelFormula : public task {
public:
int n;
int* pTot;
//Task constructor
ParallelFormula(int n_, int* pTot_) : n(n_), pTot(pTot_) {}
//Task definition
task* execute() {
//Checking task is called
for (int k = 1; k > 0; k++) {
//Calculate p number using section of Euler's formula
switch (n) {
case 0:
if (k % 2 != 0)
*pTot += 1;
else
*pTot -= 1;
cout << "Case 0" << endl;
cout << *pTot << endl;
return NULL;
case 1:
if (k % 2 != 0)
*pTot += 1;
else
*pTot -= 1;
cout << "Case 1" << endl;
cout << *pTot << endl;
return NULL;
case 2:
if (k % 2 != 0)
*pTot += 2;
else
*pTot -= 2;
cout << "Case 2" << endl;
cout << *pTot << endl;
return NULL;
}
p1 = (k*((3 * k) - 1)) / 2;
p2 = (k*((3 * k) + 1)) / 2;
if (n >= p2) {
//If p is more than 2, must call recursive function to break down problem to smaller n's, and adds result to total result P (i.e. p(n))
int x = 0;
int y = 0;
ParallelFormula& a = *new(allocate_child()) ParallelFormula(n - p1, &x);
ParallelFormula& b = *new(allocate_child()) ParallelFormula(n - p2, &y);
//Set ref_count to two children plus one for the wait
set_ref_count(3);
//Start b running
spawn(b);
//Start a running and wait for all children (a and b)
spawn_and_wait_for_all(a);
//Sum the total
if (k % 2 != 0)
*pTot += (x + y);
else
*pTot -= (x + y);
cout << "Double p" << endl;
cout << *pTot << endl;
}
else if (n >= p1) {
if (k % 2 != 0)
*pTot += serialLoop(n - p1);
else
*pTot -= serialLoop(n - p1);
cout << "Single p" << endl;
cout << *pTot << endl;
return NULL;
}
else
return NULL;
}
}
};
int parallelLoop(int n) {
int pTot = 0;
ParallelFormula& a = *new(task::allocate_root()) ParallelFormula(n, &pTot);
task::spawn_root_and_wait(a);
return pTot;
}
int main()
{
//Take inputs n and m.
cout << "Enter partition number n:" << endl;
cin >> n;
cout << "Enter modulo m:" << endl;
cin >> m;
//Start timer for serial method
tick_count serial_start = tick_count::now();
//Serial method for computing partition function modulo m.
int sP = serialLoop(n);
int serialMod = sP % m;
//Finish timer for serial method
tick_count serial_end = tick_count::now();
//Output serial results
cout << "Serial result for p(n) is: " << sP << endl;
cout << "Serial result for p(n) mod m is: " << serialMod << endl;
cout << "Serial time (s): " << (serial_end - serial_start).seconds() << endl;
//Start timer for parallel method
tick_count parallel_start = tick_count::now();
//Parallel method for computing partition function
int pP = parallelLoop(n);
int parallelMod = pP % m;
//Finish timer for parallel method
tick_count parallel_end = tick_count::now();
//Output parallel results
cout << "Parallel result for p(n) is: " << pP << endl;
cout << "Parallel result for p(n) mod m is: " << parallelMod << endl;
cout << "Parallel time (s): " << (parallel_end - parallel_start).seconds() << endl;
//Acceleration achieved
cout << "Acceleration achieved was: " << (serial_end - serial_start).seconds() / (parallel_end - parallel_start).seconds() << endl;
return 0;
};
P.S. This was partly based off of the Fibonacci sequence example in the Intel TBB documentation, so if I've done something seriously dumb by following that example then I apologise for that too XD.
The variables p1 and p2 are global but you write to them in ParallelFormula::execute concurrently. Try to declare them inside the ParallelFormula::execute method, e.g.
int p1 = (k*((3 * k) - 1)) / 2;
int p2 = (k*((3 * k) + 1)) / 2;
Also do not forget about the p variable in int serialLoop(int n) since you call this function from ParallelFormula::execute.
#include <iostream>
#include <string>
using namespace std;
// Turns a digit between 1 and 9 into its english name
// Turn a number into its english name
string int_name(int n)
{
string digit_name;
{
if (n == 1) return "one";
else if (n == 2) return "two";
else if (n == 3) return "three";
else if (n == 4) return "four";
else if (n == 5) return "five";
else if (n == 6) return "six";
else if (n == 7) return "seven";
else if (n == 8) return "eight";
else if (n == 9) return "nine";
return "";
}
string teen_name;
{
if (n == 10) return "ten";
else if (n == 11) return "eleven";
else if (n == 12) return "twelve";
else if (n == 13) return "thirteen";
else if (n == 14) return "fourteen";
else if (n == 14) return "fourteen";
else if (n == 15) return "fifteen";
else if (n == 16) return "sixteen";
else if (n == 17) return "seventeen";
else if (n == 18) return "eighteen";
else if (n == 19) return "nineteen";
return "";
}
string tens_name;
{
if (n == 2) return "twenty";
else if (n == 3) return "thirty";
else if (n == 4) return "forty";
else if (n == 5) return "fifty";
else if (n == 6) return "sixty";
else if (n == 7) return "seventy";
else if (n == 8) return "eighty";
else if (n == 9) return "ninety";
return "";
}
int c = n; // the part that still needs to be converted
string r; // the return value
if (c >= 1000)
{
r = int_name(c / 1000) + " thousand";
c = c % 1000;
}
if (c >= 100)
{
r = r + " " + digit_name(c / 100) + " hundred";
c = c % 100;
}
if (c >= 20)
{
r = r + " " + tens_name(c /10);
c = c % 10;
}
if (c >= 10)
{
r = r + " " + teen_name(c);
c = 0;
}
if (c > 0)
r = r + " " + digit_name(c);
return r;
}
int main()
{
int n;
cout << endl << endl;
cout << "Please enter a positive integer: ";
cin >> n;
cout << endl;
cout << int_name(n);
cout << endl << endl;
return 0;
}
I Keep getting this Error code:
intname2.cpp: In function âstd::string
int_name(int)â:
intname2.cpp:74: error: no match for
call to â(std::string) (int)â
intname2.cpp:80: error: no match for
call to â(std::string) (int)â
intname2.cpp:86: error: no match for
call to â(std::string) (int&)â
intname2.cpp:91: error: no match for
call to â(std::string) (int&)â
You are using digit_name, teen_name, etc as functions, when they are defined as variables. If you want to use them like that, you need to define them before your int_name function like this:
string digit_name(int n)
{
if (n == 1) return "one";
else if (n == 2) return "two";
else if (n == 3) return "three";
else if (n == 4) return "four";
else if (n == 5) return "five";
else if (n == 6) return "six";
else if (n == 7) return "seven";
else if (n == 8) return "eight";
else if (n == 9) return "nine";
return "";
}
Timothy, it looks like you're confused about the requirements of the assignment. Please make sure you understand the requirements, because at this stage it doesn't look like you know what's expected of you. You're trying to move the body of one function into the body of another function and that's simply not possible to do.
Please post the exact words that your teacher used in order for us to give you proper advice on the question.
Here are some tips for you:
If your teacher has covered switch statements then use switch statements.
Check if your teacher is not asking you to do function declarations.
Check if your teacher is not asking you to put the functions in libraries (a header file and source file).
OK scrap the tips... given your teacher's requirements I think it might look a little bit like this:
string int_name(int n)
{
int c = n; // the part that still needs to be converted
string r; // the return value
if (c >= 1000)
{
r = int_name(c / 1000) + " thousand";
c = c % 1000;
}
if (c >= 100)
{
// If you have covered switch statements then it will look like this
string digitName;
switch(c/100) // <- instead of calling digit_name(c/100), we call switch(c/100)
{
case 1:
// assign the digit name
digitName = "one";
break;
case 2:
//... fill here with your own code
break;
case 3:
//... fill here with your own code
break;
// write all the cases through 9
default:
digitName = "";
break;
}
// in the result string use the digitName variable
// instead of calling the digit_name function
r = r + " " + digitName + " hundred";
c = c % 100;
}
if (c >= 20)
{
r = r + " " + tens_name(c /10);
c = c % 10;
}
if (c >= 10)
{
r = r + " " + teen_name(c);
c = 0;
}
if (c > 0)
r = r + " " + digit_name(c);
return r;
}
Note that I'm using a switch statement, but if you your teacher hasn't shown you switch statements yet, then you can still use if/else statements:
string int_name(int n)
{
int c = n; // the part that still needs to be converted
string r; // the return value
if (c >= 1000)
{
r = int_name(c / 1000) + " thousand";
c = c % 1000;
}
if (c >= 100)
{
// declare a digitName
string digitName;
// declare a temporary value
int temp = c/100;
if(1 == temp)
{
// assign the digit name
digitName = "one";
}
else if( 2 == temp )
{
digitName = "two";
}
else if( 3 == temp )
{
// fill in the rest
}
else if( 4 == temp )
{
// fill in the rest
}
// write all the other else if statements
else
{
digitName = "":
}
// in the result string use the digitName variable
// instead of calling the digit_name function
r = r + " " + digitName + " hundred";
c = c % 100;
}
if (c >= 20)
{
r = r + " " + tens_name(c /10);
c = c % 10;
}
if (c >= 10)
{
r = r + " " + teen_name(c);
c = 0;
}
if (c > 0)
r = r + " " + digit_name(c);
return r;
}
You're going to have to take the first example with digit_name and apply it to tens_name and teen_name functions.
WARNING:
In reality you don't want to repeat the same code and clutter a single function with a bunch of code that could be in its own function. You ALWAYS want to break out repeating code into functions... if she's asking you to repeat code when you can use functions then you should be concerned. Ask your teacher if this is what she REALLY wants you to do!