I have a rand number generator.
Now my question is how do I get for instance the first/second/third/fourth digit of the generated random number.
Implementing this so the user can use a hint when guessing the number.
example: result(rand): 9876
print hint 1: second number 8
print hint 2: fourth number 6
Whats the best way to tackle this? I've been thinking to convert the string to an char array in order to print out the certain locations where the values are being kept but that won't work I guess.
Correct me if my way of asking this questions is very bold.
int nummer = 4;
std :: string result = "";
for (int i = 0; i < nummer; i++)
{
result.push_back(rand()%10 + '0');
}
You have two options for solving this problem:
Create one random number between 0 and 9999 and then calculate the individual digits.
Create four random numbers between 0 and 9 which represent the individual digits and then, if necessary, calculate the whole number from the individual digits.
Normally, doing option #1 would be more straightforward. You seem to be going for option #2. Both ways are possible and which one is better probably depends on whether your program works more with the number as a whole or with individual digits.
If you decide to do option #2, then the question arises whether you want to work with ASCII character codes between '0' and '9' (i.e. codes between 48 and 57) or with actual numbers between 0 and 9. Normally, it is a bit easier to work with the actual numbers instead of ASCII character codes, but both ways are feasible.
Personally, I would solve it the following way:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
//seed random number generator
std::srand( std::time(nullptr) );
//note that NUM_DIGITS should not be set so high
//that MAX_NUMBER is not representable as an `int`
constexpr int NUM_DIGITS = 4;
//set this to the highest possible number that
//corresponds to NUM_DIGITS
constexpr int MAX_NUMBER = 9999;
//this variable holds the entire number
int random;
//this array holds the individual digits
int digits[NUM_DIGITS];
///generate the random number
random = std::rand()%(MAX_NUMBER+1);
//calculate the individual digits of the random number
int remaining = random;
int divisor = (MAX_NUMBER+1) / 10;
for ( int i = 0; i < NUM_DIGITS; i++ )
{
digits[i] = remaining / divisor;
remaining = remaining % divisor;
divisor/= 10;
}
//print the whole random number
std::cout << "Whole random number:\n" << random << "\n\n";
//print the individual digits
std::cout << "Individual digits:\n";
for ( int i = 0; i < NUM_DIGITS; i++ )
{
std::cout << digits[i] << "\n";
}
}
Sample output (actual output depends on random number seed):
Whole random number:
8695
Individual digits:
8
6
9
5
I've been thinking to convert the string to an char array but that won't work I guess.
I see no reason to do this. In your posted code, you can simply write
result[0]
result[1]
result[2]
result[3]
to access the individual digits of the number.
In that respect, converting a std::string to a C-style character array has no advantages.
The code you've written is fine.
Whether you store the characters in an array or a string, you can access the elements using result[i] where i starts at 0.
I've been thinking to convert the string to an char array but that won't work I guess.
Using std::string is usually a better idea - still possible but a little harder to screw them up, and they're more powerful generally, but you could use a char array if you wanted:
char result[] = "0000"; // will have null terminator
for (int i = 0; i < 4; ++i)
result[i] = rand() % 10 + '0';
Letting result be a 5-character array - with a null terminator - means you can still print all four digits easily with std::cout << result.
Alternatively, you could pick a random 4-digit number and convert it to a string of a particular width, using '0's to pad:
#include <iostream>
#include <iomanip>
int main() {
std::ostringstream oss;
oss << std::setw(4) << std::setfill('0') << rand() % 10000;
std::cout << '[' << oss.str() << "]\n";
}
Related
Hello everyone and thank you for taking your time to answer this very stupid but for me tough question. I have spent so much time trying to figure out how to do this, yet some may find this very simple. The exercise goes like this: "Write the program, that contains a function "numbers", which
will print all four-digit numbers which: all digits are odd and
do not contain a digit 0."
My code is below but if anyone knows how to write a better code than to just correct mine, please share it in the comments.
#include <iostream>
using namespace std;
/* s is the remain when dividing i by 10 */
void numbers ()
{
for (int i = 9999; i >= 1000; i/=10)
{
int s = i % 10;
if (s % 2 == 1 && s != 0)
{
cout << i << endl;
}
i/=10;
}
}
int main()
{
numbers();
return 0;
}
We can approach the problem by analyzing the requirements.
So, we need odd digits. There are only 5 odd digits: 1,3,5,7,9. Any number that we create can consist only of those 5 digits.
The second observation is that there are 5^(NumberOfDigits) different numbers. That is easy to understand. Example: For the first digit, we have 5 possibilities. And then, for each of this 5 digits we have again 5 possible second digits. So, now already 5*5=25 numbers. And for each of the 5 second digits we have again 5 third digits, so, 125 numbers. And for a 4 digit number, we have 5*5*5*5=5^4=625 different numbers.
Good, how to find them? It is obvious, that the delta between two odd digits is 2. Or with other words, if we have an odd digit, we can simply add 2 to get the next odd digit. After the 9, we will have an overflow and need to continue again with 1.
There are many potential designs for the solution.
I will show here an example, were I do not use a complete number, but an array of digits. Then I will add 2 to one digit and if there is an overflow, I will also add 2 to the next digit and so on and so on. Somehow simple.
We do this, until the most significant digit will flip to one, and then all digits are 1 again.
#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>
#include <iomanip>
// Number of digits in a number
constexpr size_t NumberOfDigits = 4u;
// Representation of the number as an array of digits
using Digits = std::array<int, NumberOfDigits>;
// Get the next number/digits
constexpr void nextDigits(Digits& digits) noexcept {
// Starting at the least significant digit
for (int i{ NumberOfDigits-1 }; i >= 0; --i) {
// Get the next odd number
digits[i] += 2;
// Check for overflow, then reset to 1, else stop
if (digits[i] > 9) digits[i] = 1;
else break;
}
}
int main() {
// Define our array with digits and fill it with all one
Digits d{};
std::fill(d.begin(), d.end(), 1);
// Some counter, Just for display purposes
unsigned long long i = 1;
do {
// Some debug output
std::cout << std::right << std::setw(30) << i++ << " --> ";
std::copy(d.begin(), d.end(), std::ostream_iterator<int>(std::cout));
std::cout << '\n';
// And, get the next number/digits
nextDigits(d);
// Do this, until we have found all numbers
} while (not std::all_of(d.begin(), d.end(), [](const int i) {return i == 1; }));
}
Again, this is one of many potential solutions
The Problem:
A company is distributing phone numbers to its employees to make things easier. the next digit cannot be equal to the last is the only rule for example 0223 is not allowed while 2023 is allowed. At least three digits will be excluded every time. Write a function that takes in a length of the phone number and the digits that will be excluded. The function should print all possible phone numbers.
I got this question in an interview and I have seen one like it before at my university. It is a permutation problem. My question is what is the best way or decent way to solve this without a million for loops.
I do understand that this is technically how it works
length of phone number = 3;
[0-9], [0-9] excluding the last digit, [0-9] excluding the last digit
but I am unsure on how the best way to turn this into code. Any language is accepted!
thank you:
Also I might be asking this in the wrong place. please let me know if I am.
A simple way to solve this problem could be using Recursion. Here's my commented C++ code:
void solve(int depth, int size, vector <int> &curr_seq){
// If the recursion depth is equal to size, that means we've decided size
// numbers, which means that curr_seq.size() == size. In other words, we've
// decided enough numbers at this point to create a complete phone number, so
// we print it and return.
if(depth == size){
for(int item : curr_seq){
cout << item;
}
cout << "\n";
return;
}
// Try appending every possible digit to the current phone number
for(int i = 0; i <= 9; ++i){
// Make sure to only append the digit i if it is not equal to the last digit
// of the phone number. We can also append it, however, if curr_seq
// is empty (because that means that we haven't decided the 1st digit yet).
if(curr_seq.empty() || curr[curr.size() - 1] != i){
curr_seq.push_back(i);
solve(depth + 1, size, curr);
curr_seq.pop_back();
}
}
}
I think I like the recursive solution, but you can also just generate all permutations up to the limit (iterate), filter out any with repeating digits, and print the successful candidates:
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
// Because C/C++ still has no integer power function.
int ipow(int base, int exp) {
int result = 1;
for (;;) {
if (exp & 1)
result *= base;
exp >>= 1;
if (!exp)
return result;
base *= base;
}
}
void noconsec(const int len) {
int lim = ipow(10, len);
// For e.g. len 4 (lim 10000),
// obviously 00xx won't work, so skip anything smaller than lim / 100.
int start = (len <= 2) ? 0 : (lim / 100);
for (int num = start;num < lim;num++) {
// Convert to string.
std::stringstream ss;
ss << std::setw(len) << std::setfill('0') << num;
std::string num_s = ss.str();
// Skip any consecutive digits.
bool is_okay = true;
auto prev_digit = num_s[0];
for (int digit_idx = 1;digit_idx < num_s.length();digit_idx++) {
auto digit = num_s[digit_idx];
if (prev_digit == digit) {
is_okay = false;
}
prev_digit = digit;
}
// Output result.
if (is_okay) {
cout << num_s << "\n";
}
}
}
int main(const int argc, const char * const argv[]) {
noconsec(4);
}
Differences to note, this needs an integer power function to compute the limit. Converting an int to a string and then checking the string is more complex than constructing the string directly. I guess it could be useful if you have a list of integers already, but mostly I did it for fun.
How to obtain rightmost unset bit position of a number N in c++.
1<= N <= 2^60
storing as number does not work since 2^60 can only be stored in string.
thus following does not work
long long getBitUtil(long long n) {
return log2(n&-n)+1;
}
long long getBit(long long n) {
return getBitUtil(~n);
}
Try this. Code is self explanatory with comments
int getRightmostUnSetBit(string s, int pos)
{
int l= s.size();
int lc = s[l-1];
if(lc>=48 && lc<=57 && lc%2 ==0)
return pos; // if last digit is even return position
else
{// divide the number into half and call function again.
string s2 = "";
int rem =0;
for(int i =0; i<l;i++)
{
int d = s[i]-'0';
d = rem *10 + d;
int q = d/2;
rem = d%2;
s2.push_back('0'+q);
}
return getRightmostUnSetBit(s2,pos+1); //call for s2
}
}
Take input in string and call from main
int pos = getRightmostUnSetBit(s,1);// will not work if s is "0" or similar to "000...". So check for it before function calling.
For normal integers the solution is basically given in the book Hackers Delight. I can only refer to the book. I cannot copy. But section 2.1 gives already good hints.
Depending on your OS you will most likely have 64 bit data types. With 64 bit data types, you can still use arithmentic solutions for your given number range. Above that, you should use string representations.
Then we will convert a big decimal number given as string into a string containing its binary equivalent.
Then we search for the last 0 in the resulting binary string.
The secret is to do a division by 2 for a number given as string. This can be done as we learned in school on a piece of paper.
And then check, if the number is even or odd and put a 1 or 0 respectively in the resulting string.
This will work for abitrary big numbers. Limiting factor (but here not really) is the length of the resulting binary string. That must fit into a std::string :-)
See:
#include <string>
#include <iostream>
#include <bitset>
#include <iterator>
#include <regex>
#include <stack>
#include <algorithm>
// Odd numbers. We will find out, if a digit is odd or even
std::string oddNumbers{ "13579" };
// Devide a number in a string by 2. Just like in school on a piece of paper
void divideDecimalNumberAsStringBy2(std::string& str)
{
// Handling of overflow during devisions
unsigned int nextNumberToAdd{ 0 };
// The resulting new string
std::string newString{};
// Go through all digits, starting from the beginning
for (char& c : str) {
// Get overflow for next round
unsigned int numberToAdd = nextNumberToAdd;
// Get the overflow value for the next devision run. If number is odd, it will be 5
nextNumberToAdd = (oddNumbers.find(c) != std::string::npos) ? 5 : 0;
// Do the devision. Add overflow from last round
unsigned int newDigit = (c - '0') / 2 + numberToAdd;
// Build up newe string
newString += static_cast<char>(newDigit + '0');
}
// Remove leading zeroes
str = std::regex_replace(newString, std::regex("^0+"), "");
}
// Convert a string with a big decimal number to a string with a binar representation of the number
std::string convertDecimalStringToBinaryString(std::string& str)
{
// Resulting string
std::string binaryDigits{};
// Until the string is empty. Will be shorter and short because of devision by 2
while (!str.empty()) {
// For an even number we add 0, for an odd number we add 1
binaryDigits += (oddNumbers.find(str.back()) == std::string::npos) ? '0' : '1';
// And devide by 2
divideDecimalNumberAsStringBy2(str);
}
// Bits come in wrong order, so we need to revers it
std::reverse(binaryDigits.begin(), binaryDigits.end());
return binaryDigits;
}
int main()
{
// Initial string with a big number. Get input from user
std::string bigNumber{};
std::cout << "Enter big number: ";
std::cin >> bigNumber;
// Convert it
std::string binaryDigits = convertDecimalStringToBinaryString(bigNumber);
// Find the last 0
unsigned int posOfLast0 = binaryDigits.rfind('0');
// Show result
if (posOfLast0 == std::string::npos)
std::cout << "\nNo digit is 0 --> " << binaryDigits << '\n';
else
std::cout << "\nSize of resulting string: "<< binaryDigits.size() << "\nPos of last 0: " << posOfLast0+1 << "\nBinary String:\n\n" << binaryDigits << '\n';
return 0;
}
this is a super simple problem but it's late and I cant figure out for the life of me why this function doesnt work. I want it to print 1234, but instead it prints 123121. can someone explain what's going on and how to fix it? thanks
#include <iostream>
const int size = 20;
void set_int( int num )
{
int digits[size];
for ( int i = size - 1; i >= 0; i-- )
{
digits[i] = num % 10;
num /= 10;
if ( num != 0 )
std::cout << num;
}
}
int main()
{
set_int( 1234 );
return 0;
}
Well you are outputting the number instead of the digit.
Try changing like,
cout << digits[i]
Further clarification :
On the first run of the loop your num will be 1234 / 10 = 123
Next run your number will be 123 / 10 = 12
Next is going to be 1
You are outputing num, so you get 123121 .
There are several things wrong with that code.
Firstly, the definition
int digits[size];
is a variable length array, which is valid C (since the 1999 C standard) but is not valid C++. Unfortunately, some C++ compilers support such things as an extension.
Second, even if we assume that definition is valid, your code is essentially stating that you need an array with 1234 elements to hold integral values corresponding to four digits (1,2,3, and 4).
As MichaelCMS has described, your code is outputting something other than the digits too. A value of 1234 has 4 digits, so you would need to loop a total of 4 times to find all digits (if doing it right). You would not need to loop 1234 times.
MichaelCMS explained correctly, why you have such output. There are mistakes in your function. I wrote another one.
You can use next code, which helps to find digits of number.
#include <iostream>
int FindNumberOfDigits(int number);
void SplitNumberIntoDigits(int number);
// Splits number into digits.
// Works with not big numbers.
void SplitNumberIntoDigits(int number)
{
int size = FindNumberOfDigits(number);
int * digits = new int[size];
int divider = 0;
int degree = 0;
for(int digit = size; digit > 0; digit --)
{
// Find degree of divider
degree = digit;
// Find divider for each digit of number.
// For 1234 it will be 1000. For 234 it will be 100.
divider = pow(10, degree - 1);
// We use "abs" to get digits without "-".
// For example, when -1234 / 1000, you get -1.
digits[digit] = abs(number / divider);
// Cut number to find remaining digits.
number %= divider;
std::cout << digits[digit];
}
std::cout << std::endl;
}
// If number = 0, number of digits will be 1.
// Else returns number of digits.
int FindNumberOfDigits(int number)
{
int digitsNumber = 0;
if (number)
{
// calculates number of digits
while (number / 10)
{
number /= 10;
digitsNumber ++;
}
}
digitsNumber += 1;
return digitsNumber;
}
int _tmain(int argc, _TCHAR* argv[])
{
SplitNumberIntoDigits(1234);
SplitNumberIntoDigits(0);
SplitNumberIntoDigits(1);
SplitNumberIntoDigits(-1234);
SplitNumberIntoDigits(1234567890);
return 0;
}
As a result this code can help you to find digits of not big numbers. It works with positive, negative numbers and zero.
I would like to convert an integer into an array, so that it looks like the following:
int number = 123456 ;
int array[7] ;
with the result:
array[0] = 1
array[1] = 2
...
array[6] = 6
Perhaps a better solution is to work backwards:
123456 % 10 = 6
123456 / 10 = 12345
12345 % 10 = 5
12345 / 10 = 1234
just use modular arithmetic:
int array[6];
int number = 123456;
for (int i = 5; i >= 0; i--) {
array[i] = number % 10;
number /= 10;
}
You can extract the last digit of the number this way:
int digit = number % 10;
number /= 10;
Note that you should also check whether number is positive. Other values require additional handling.
Here what I came up with, the integerToArray function returns a vector that is converted from the integer value. you can test it with the main function as well:
#include <iostream>
#include <vector>
using namespace std;
vector <int> integerToArray(int x)
{
vector <int> resultArray;
while (true)
{
resultArray.insert(resultArray.begin(), x%10);
x /= 10;
if(x == 0)
return resultArray;
}
}
int main()
{
vector <int> temp = integerToArray(1234567);
for (auto const &element : temp)
cout << element << " " ;
return 0;
}
//outputs 1 2 3 4 5 6 7
Take the log10 of the number to get the number of digits. Put that in, say pos, then, in a loop, take the modulo of 10 (n % 10), put the result in the array at position pos. Decrement pos and divide the number by 10. Repeat until pos == 0
What did you want to do with the sign if it's negative?
#include <cmath>
#include <vector>
std::vector<int> vec;
for (int i = log10(input); i >= 0; i--)
{
vec.push_back(input / int(std::pow(10, i)) % 10);
}
Might be a good approach, I think
The easiest way I can imagine now is:
char array[40];
int number = 123456;
memset(array, 0x00, sizeof(array));
sprintf(array, "%d", number);
Additionally you can convert each digit to int just subtracting the char value by 0x30.
EDIT: If this is a homework, your teacher you probably ask you to write the program using % operator though (example 12 % 10 = 2). If this is the case, good homework ;-)
You can use modulus to determine the last digit.
And you can use division to move another digit to the last digit's place.
You can't simply "convert" it. The integer is not represented in software in decimal notation. So the individual digits you want don't exist. They have to be computed.
So, given an arbitrary number, how can you determine the number of ones?
We could divide by ten, and then take the remainder: For 123, the division would give 12, and then there's a remainder of 3. So we have 3 ones. The 12 tells us what we have past the ones, so it can be our input for the next iteration. We take that, divide by 10, and get 1, and a remainder of 2. So we have 2 in the tens place, and 1 left to work with for the hundreds. Divide that by 10, which gives us zero, and a remainder of 1. So we get 1 in the hundreds place, 2 in the tens place, and 3 in the ones place. And we're done, as the last division returned zero.
See SO question Language showdown: Convert string of digits to array of integers? for a C/C++ version (as well as other languages).
if this is really homework then show it your teacher - just for fun ;-)
CAUTION! very poor performance, clumsy way to reach the effect you expect and generally don't do this at home(work) ;-)
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
typedef std::vector< int > ints_t;
struct digit2int
{
int operator()( const char chr ) const
{
const int result = chr - '0';
return result;
}
};
void foo( const int number, ints_t* result )
{
std::ostringstream os;
os << number;
const std::string& numberStr = os.str();
std::transform(
numberStr.begin(),
numberStr.end(),
std::back_inserter( *result ),
digit2int() );
}
int main()
{
ints_t array;
foo( 123456, &array );
std::copy(
array.begin(),
array.end(),
std::ostream_iterator< int >( std::cout, "\n" ) );
}
If you wanted to turn it into a string then it would be really easy, just do what everyone else is saying about using the % operator:
Let's say num = 123, we can do this:
string str;
while (num > 0)
{
str = (num % 10) + str; //put last digit and put it into the beginning of the string
num = num /10; //strip out the last digit
}
Now you can use str as an array of chars. Doing this with an array is a hassle because putting things in the beginning of an array requires you to shift everything else. What we can do is, instead of putting each digit into a string, we can put it into a stack. It will put it in a backwards order like this: 3 2 1. Then we can pop off the top number one by one and put that into an array in the correct order. You array will look like this: 1 2 3. I will leave the implementation to you since this is homework.
#Broam has a good solution, but like he stated, it's for working backwards. I think the OP or whoever comes looking into this thread will want it forwards and that's why I'm posting this. If you have a better solution, please reply, I'm interested as well.
To convert an integer to array, you can do the steps below:
Get the total number of digits in a number to which we want to convert to
array.For this purpose, we will use count_digits() function which will return total no of digits after ignoring leading zeros.
digits = count_digits(n);
Now we will dynamically allocate memory for our resulting array, just like
int* arr = new int[count_digits(n)]
After allocating memory, we will populate the array using the for loop below
int digits = count_digits(num);
for (int i = digits; i > 0; i--){
arr[i-1] = num % 10;
num = num / 10;
}
After performing the steps above, we will be able to convert an integer to array. Remember, num is the number that we want to convert into array and digits is the variable which gives us the number of digits in a given number ignoring leading zeros.