organizing strings using a hash table C++ - c++

I'm writing a code that:
asks for a string
converts that string into it's ascii value
then send this number to folding function that only take the first 8 digits
from the right , split it into 3 numbers , add them together ,then take the first 3 digits from the right as well
this number with 3 digits is the order of the the string in an array of pointers that represent the hash table
For example: If I input the string "abclmn" -> 979899100108109110 -> folding function 08109110 split the number into 3 numbers like so -> 081,091,10 -> 81+91+10=182
and 182 is where the string "abclmn" should be inserted in the hash table
This is my code:
#include<iostream>
#include<cmath>
#include<string>
#include<queue>
using namespace std;
int folding(long int num1)
{
int num;
num=num1%100000000;
int x=num/100000;
int y=(num%100000)/100;
int z=num%100;
int w=(x+y+z)%1000;
return w;
}
int main()
{
string s;
cout<<"input the variable name"<<endl;
cin>>s;
int* a=new int [s.length()];
for (int i=0;i<(s.length());++i)
{
a[i]=(int)s[i];
}
queue<int> q;
for (int i=0;i<(s.length());++i)
{
if (a[i]<10) q.push(a[i]);
else
if ((a[i]>9)&&(a[i]<100))
{
q.push(a[i]/10);
q.push(a[i]%10);
}
else if (a[i]>100)
{
q.push(a[i]/100);
q.push((a[i]%100)/10);
q.push(a[i]%10);
}
}//filling the number in a queue
long int num=0;
for (int i=(q.size());i>0;--i)
{
num=num+(q.front()*pow(10*1.0,i-1));
q.pop();
}
cout<<"the answer"<<folding(num)<<endl;
system("pause");
return 0;
}
My problem is that I don't know how long the string will be
so if the string is too along the output is going to be a random value
and that's because I'm using long int for the output value and it's not enough.
So is there a solution for this or another way to get the same result?
Thanks for help.

convert that string into it's ascii value
then send this number to
folding function that only take the first 8 digits from the right ,
split it into 3 numbers , add them together ,then take the first 3
digits from the right as well
Well, since you're only interested in the last 8 digits, we don't need to convert the entire string to its ASCII representation.
Let's try traversing backwards along the string and building our number that way.
int getDigits( std::string s ) {
long long int digits = 0;
int runningLength = 0;
int prevLength = 0;
for ( auto it = s.rbegin(); it != s.rend(); ++it ) {
runningLength += prevLength;
//if digits is a 7 digit number then appending a 3 digit number would overflow an int
digits += (long long int)*it * pow(10, runningLength);
//we have to work out the length of the current digit
//so we know how much we need to shift by next time
int dLength = 0;
for ( int d = *it; d > 0; dLength++, d /= 10 );
prevLength = dLength;
if ( digits >= 100000000 ) break;
}
return digits % 100000000;
}
then send this number to folding function that only take the first 8
digits from the right , split it into 3 numbers , add them together
,then take the first 3 digits from the right as well
Your code looks fine for that.
The code to split the string into digits would be a lot neater if you worked in base 16 (and assumed printable ASCII only).

Related

How to solve Permutation of a phone number problem

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.

finding the number of possible decodings of the given number(dynamic programming)

I am trying to solve a problem where every letter has a respective number such as a-1,b-2....z-26.
Now given a number, in how many ways can the number be decoded is the question. consider an example where 25114 can be decoded as 'BEAN',‘BEAAD’, ‘YAAD’, ‘YAN’, ‘YKD’ and ‘BEKD’. this could be decoded in 6 ways.
I have written code in c++ but I am getting the wrong answer. Please correct my code.
#include<bits/stdc++.h>
using namespace std;
int total = 0;
int arr[100001];
void func(int start,int end,int factor){
if(start==end)
return;
int j =start;
if(factor==2&&j==end-1)//if j is the last element and factor is 2,accessing j+1 element is illegual
return;
if(factor==2){
if((arr[j]*10+arr[j+1])>26)
return;
else{
total++;
func(start+2,end,1);
func(start+2,end,2);
}
}
else{//factor is 1
total++;
func(start+1,end,1);
func(start+1,end,2);
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int p;
cin>>p;
arr[i]=p;
}
func(0,n,1);
func(0,n,2);
cout<<total<<endl;
return 0;
}
essentially what my code is doing is that it fixes one number from the given array(using one digit or two digits from the the given array) and recurses until all the combinations are covered. for example considering the above case, I first choose '2' as my first digit and decode it as 'B'(factor = 1) and then choose '25' and decode it as 'E'(factor = 2).
**following are the input and output from the following code
input : 25114
expected output : 6
my output : 15
input : 3333333333(10 digits)
expected output : 1
my output : 10
Based on the original program from the question I suggest to count the encodings when you reach the end only (if(start==end)).
As func will always be called twice with factor=1 and factor=2, I can freely choose either condition for counting.
Here is the modified code:
#include<bits/stdc++.h>
using namespace std;
int total = 0;
int arr[100001];
void func(int start,int end,int factor){
if(start==end) {
if(factor == 1) total++; // count once when reaching the end
return;
}
int j =start;
if((factor==2) && (j==end-1))//if j is the last element and factor is 2,accessing j+1 element is illegal
return;
if(factor==2){
if((arr[j]*10+arr[j+1])>26)
return;
else{
//total++;
func(start+2,end,1);
func(start+2,end,2);
}
}
else{//factor is 1
//total++;
func(start+1,end,1);
func(start+1,end,2);
}
return;
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int p;
cin>>p;
arr[i]=p;
}
func(0,n,1);
func(0,n,2);
cout<<total<<endl;
return 0;
}
This calculates the expected results from the example input in the question.
$ echo 5 2 5 1 1 4|./program
6
$ echo 10 3 3 3 3 3 3 3 3 3 3|./program
1
There is room for improvement.
Instead of modifying a global variable I would return the number of combinations from func and add the values in the higher level.
I would also handle the distinction between 2-digit and 1-digit numbers in the called func instead of in the caller.
Something like this pseudo code:
int func(int start, int end)
{
if(remaining length is <2) {
// we reached the end, so this is one combination
return 1;
}
if(two-digit number is >26) {
// only a 1-digit number is possible, count remaining combinations
return func(start+1, end);
}
// both a 1-digit or 2-digit number is possible, add the remaining combinations for both cases
return func(start+1) + func(start+2);
}
Your question is tagged as "dynamic-programming", but it is anything but.
Instead, think about the state space and its boundary conditions:
The empty string has zero encodings;
A single digit has a single encoding;
An n-digit string has as many encodings as an (n-1)-digit substring plus as many encodings as an (n-2)-digit substring if the first two digits are <= 26.
Thus, we can walk the string from back to front and store the intermediate results for reuse:
uint64_t solve(std::vector<int>& digits) {
const int n = digits.size();
std::vector<int> encodings(n+1);
encodings[n] = 1;
for (int i = n-1; i >= 0; i--) {
bool two_digits_fit = (i < n - 1) && (digits[i] * 10 + digits[i+1]) <= 26; // What if digits[i] == 0?
encodings[i] = encodings[i+1] + (two_digits_fit ? encodings[i+2] : 0);
}
return encodings[0];
}

putting ints into an array c++

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.

How to get one individual digit from a number that has more than one digit in it

So I have a four digit number that is player-input in a simple puzzle I am making, I want to be able to check each digit, say I want to check the second digit to the right, if the number happens to be 4601 then of course it will be 6 but is their a faster way other than testing every single four digit number?
I found a few results with search but they didn't help, they just confused me more, please phrase any answers so anyone can understand them.
Also i am using c++.
To retrieve the second most significant (base ten) digit from an arbitrary integer i you could do:
while (i >= 100)
i /= 10;
return i % 10;
Of course, this assumes the number greater than or equal to 10 to begin with. If you need to preserve the number, then you will (obviously) want to be operating on a copy.
EDIT:
One could define a function for extracting an arbitrary digit using either arithmetic or string operations.
Arithmetic solution:
int extractDigit(size_t digit, int n) {
int mask = 1;
while ( digit --> 0 )
mask *= 10;
if (n < mask / 10) { // insufficient digits
return -1; // or some other appropriate error handling.
while ( n >= mask )
n /= mask;
return n % 10;
}
String solution:
#include <sstream>
#include <string>
using std::string;
using std::stringstream;
int extractDigit(size_t digit, int n) {
string result = static_cast<stringstream&>(stringstream() << n).str();
if (result.size() < digit) {
return -1;
}
return result[digit-1] - '0';
}
Both of these solutions implicitly assume that n will be non-negative. You could enforce this pre-condition by using an unsigned data type if you need to. Also, both of these functions are defining the digit positions such that the most significant is in position 1, and the positions increase to the right.
I am not guessing anything about what you going to do after you have the digit.But if its only the digit you want to have then you could use below:
int a=1234;
char b[4];
sprintf(b,"%d",a);
char c=b[1];
Now c has the second digit of your 4 digit number.
like wise you can access all the digits using the index to character array b
for a c++ equivalent pls see below:
std::ostringstream out;
out << age;
Now out.str()[1] will show the second digit.
You can read the number as an int and convert it to a char array and check each char as a digit
Example:
char digits[5];
int number;
//Read number in
scanf("%d",&number);
//Make sure it's 4 digits
number%=10000;
//Convert it to a char array
sprintf(digits,"%d",number)
if(digits[1]=='6')
{
//do stuff
}

Convert integer to array

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.