I had a problem from a website. Given a string s and st, I have to found all possible combination of st in s. For example,
s = "doomdogged"
st = "dg"
answer = 4
I can choose the d from 0 or 4, and g from 6 or 7. Which gives me 4 possible combinations.
Here's my code:
#include <iostream>
#include <vector>
using namespace std;
string s, st;
bool target[26];
vector<int> positions[26];
vector<vector<int>> possibleCombinations;
void DFS_Enumeration(int, vector<int>*);
int DFS_index_max = 0;
int main(int argc, char *argv[])
{
int answer = 0;
cin >> s; //Given a string s
cin >> st; //Given a string st
//Find all possible combination of st in s
for ( int i = 0 ; i < 26 ; ++ i )
target[i] = 0;
for ( int i = 0 ; i < st.length() ; ++ i )
target[st[i] - 97] = 1;
for ( int i = 0 ; i < 26 ; ++ i )
{
if ( target[i] == 0 ) continue;
for ( int j = 0 ; j < s.length() ; ++ j )
{
if ( s[j] == i + 97 ) positions[i].push_back(j);
}
}
DFS_index_max = st.length();
vector<int> trail(0);
DFS_Enumeration(0, &trail); //Here I got an runtime error
for ( vector<int> vi : possibleCombinations )
{
int currentMax = 0;
for ( int i = 0 ; i < vi.size() ; ++ i )
{
if ( vi[i] > currentMax )
{
if ( i == vi.size() - 1 ) ++ answer;
currentMax = vi[i];
continue;
}
else
break;
}
}
cout << answer;
}
void DFS_Enumeration(int index, vector<int>* trail)
{
if ( index == DFS_index_max )
{
possibleCombinations.push_back(*trail);
return;
}
for ( int i = 0 ; i < positions[st[index] - 97].size() ; ++ i )
{
trail -> push_back(positions[st[index] - 97][i]);
DFS_Enumeration(++index, trail);
trail -> pop_back();
}
return;
}
First I look for characters in st, and mark them as needed to found in my boolean array target.
Then, I use DFS to enumerate all possible combinations. For the above example of "doomdogged" and "dg", d exists in 0, 4, 9. And g exist in 6, 7. I will get 06, 07, 46, 47, 96, 97.
Lastly, I count those which make sense, and output the answer. For some reason, my code doesn't work and generate an runtime error concerning memory at the line I've marked.
DFS_Enumeration might increment index any number of times, so st[index] could likely be past the end of the string st.
Related
Program: So I made a program that take two numbers, N and L. N is the size of a 2D array and L is a number from 3 - 16. The program builds the array and starts at the center and works its way out in a counter clockwise spiral. I is the value of the center and its as you go through the array( in the spiral ) the value will increase by one. It it is prime, that number will be assigned to that spot and if not it * will take its place instead.
Error: I'm getting a "Floating point exception " error, how would I solve this?
Code:
void Array_Loop( int *Array, int n, int L ) ;
int Is_Prime( int Number ) ;
int main( int argc, char *argv[] ){
int **Array ;
int n, L ;
n = atoi( argv[1] ) ;
L = atoi( argv[2] ) ;
Matrix_Build( &Array, n, n ) ;
Array_Loop( Array, n, L ) ;
return 0 ;
}
void Array_Loop( int *Array, int n, int L ){
int i, j, k, h ;
int lctn, move;
lctn = n / 2 + 1 ;
i = lctn ;
j = lctn ;
move = 1
while( i != 0 && j != n ){
for( j = lctn ; j < lctn + move ; j++ ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move = move * -1 ;
for( i = i ; i > lctn - move ; i-- ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move-- ;
for( j = j ; j > lctn - move ; j-- ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move = move * -1 ;
for( i = i ; i < lctn - move ; i-- ){
if( L % 2 == 2) Array[i][j] = -1 ;
else Array[i][j] = Is_Prime( L ) ;
L++ ;
}
move++ ;
}
}
int Is_Prime( int Number ){
int i ;
for( i = 0 ; i < Number / 2 ; i++ ){
if( Number % i != 0 ) return -1 ;
}
return Number ;
}
You are getting Floating point exception because Number % i, when i is 0:
int Is_Prime( int Number ){
int i ;
for( i = 0 ; i < Number / 2 ; i++ ){
if( Number % i != 0 ) return -1 ;
}
return Number ;
}
Just start the loop at i = 2. Since i = 1 in Number % i it always be equal to zero, since Number is a int.
Floating Point Exception happens because of an unexpected infinity or NaN.
You can track that using gdb, which allows you to see what is going on inside your C program while it runs. For more details:
https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_gdb.php
In a nutshell, these commands might be useful...
gcc -g myprog.c
gdb a.out
gdb core a.out
ddd a.out
I'm developing a class for large number arithmetic, it now knows how to do addition, handle cin and cout.
It, however has very limited and basic subtraction functionality, and does not know how to handle negative. But that can be easily resolved.
My question is this, how to do multiplication.
I will detail how it handle cin and cout here.
For cin, it will save integers to value[500], for example, 50 will be saved to value[498] and value[499]. BUT NOT value[0] and value[1]
For cout, it will scan for the first non-zero value from value[0] to value[499], and then output from that non-zero value to the end. Also, if it finds no non-zero value, it will output 0.
Here's my code:
#include <iostream>
using namespace std;
class largeNumber {
public:
int value[500];
largeNumber()
{
for ( int i = 0 ; i < 500 ; ++ i )
{
value[i] = 0;
}
}
//below are arithmetic operations
largeNumber operator+(const largeNumber &ln) const
{
largeNumber result;
for ( int i = 0 ; i < 500 ; ++ i )
{
result.value[i] = value[i] + ln.value[i];
}
for ( int i = 499 ; i >= 0 ; -- i )
{
if ( result.value[i] >= 10 )
{
result.value[i - 1] += ( result.value[i] / 10 );
result.value[i] %= 10;
}
}
return result;
}
largeNumber operator-(const largeNumber &ln) const
{
largeNumber result;
for ( int i = 0 ; i < 500 ; ++ i )
{
result.value[i] = value[i] - ln.value[i];
}
for ( int i = 499 ; i >= 0 ; -- i )
{
if ( result.value[i] < 0 )
{
--result.value[i - 1];
result.value[i] += 10;
}
}
return result;
}
largeNumber operator*(const largeNumber &ln) const
{
largeNumber result;
for ( int x = 499 ; x >= 0 ; -- x )
{
for ( int y = 499 ; y >= 0 ; -- y )
{
int dx = 499 - x;
int dy = 499 - y;
int dr = dx + dy;
int r = 499 - dr;
if ( r >= 0 && r <= 499 )
{
result.value[r] = value[x] * ln.value[y];
}
}
}
for ( int i = 499 ; i >= 0 ; -- i )
{
if ( result.value[i] >= 10 )
{
result.value[i - 1] += ( result.value[i] / 10 );
result.value[i] %= 10;
}
}
return result;
}
//below are cin, cout operators
friend ostream& operator<<(ostream& out, const largeNumber& ln)
{
bool valueFound = false;
for ( int i = 0 ; i < 500 ; ++ i )
{
if ( ln.value[i] != 0 )
{
valueFound = true;
}
if ( valueFound == true )
{
out << ln.value[i];
}
}
if ( valueFound == false )
{
out << "0";
}
return out;
}
friend istream& operator>>(istream& in, largeNumber& ln) // input
{
string str;
in >> str;
int length = str.length();
for ( int i = 500 - length ; i < 500 ; ++ i )
{
ln.value[i] = (str[length-(500-i)] - 48);
}
return in;
}
};
int main()
{
largeNumber a, b;
string op;
cin >> a >> op >> b;
cout << a * b;
return 0;
}
I've included my way to do multiplication, however it is flawed.
By the way, the number given by teacher promised that the result of multiplication will be a number less than 500 digit.
Lets start with simple multiplication(Long multiplication):
112 * 301
1 1 2
3 0 1
______________
1 1 2
0 0 0
3 3 6
_______________________
3 3 7 1 2
So, this needs N by N matrix as rows to be added with shifting-n-times.
Where are you doing this addition and where is shifting?
For your question, it would need 500 x 500 multiplications and 500 x 500 additions. O(N*N)
Pro: each digit-multiplication can be done in a single byte so you can change the structure of digits that your compiler can vectorize the code and multiply 16 to 32 digits at once(unrolls quite good).
Con: too many computing(nearly 25-40 iteration per 500 digits-num)
Note: GPU-powered calculus could give it roughly 40x more speed. Such as OpenCL or Cuda.
I am new to C++. I want to calculate the no of transitions from 0 to 0, 0 to 1, 1 to 0 and 1 to 1 in a 9 bit sequence. I have written the following code;
int main {
srand((unsigned)time(0));
unsigned int x;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9>bitseq(x);
for(int j=0;j<=bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&(b==0)==0)
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&(b==1)==0)
{
transition0_1 = transition0_1 + 1;
else if ((a==1)&(b==0)==0)
{
transition1_0 = transition1_0 + 1;
else
{
transition1_1 = transition1_1 + 1;
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
}
}
Somebody please guide me on the following
how to save the last bit value in loop-2 to check the transition from last bit of the last bitset output to the 1st bit of the next bitset output?
If this does not work, How I can save it in vector and use iterators to check the transitions?
First of all, the loop index j is running past the end of the bitset. Indices go from 0 to bitseq.size()-1 (inclusive). If you're going to test j and j+1 the largest value j can take is bitseq.size()-2.
Second, the ==0 part that appears in your ifs is strange, you should just use
if( (a==0)&&(b==0) )
Notice the use of two &&. While a single & works for this code, I think it's better to use the operator that correctly conveys your intentions.
And then to answer your question, you can keep a "last bit" variable that is initially set to a sentinel value (indicating you're seeing the first bitseq just now) and compare it to bitseq[0] before the start of loop 2. Here's a modified version of your code that should do what you ask.
int main {
srand((unsigned)time(0));
unsigned int x;
int transition0_0 = 0,
transition0_1 = 0,
transition1_0 = 0,
transition1_1 = 0;
int prev = -1;
for (int i=0:i<=512;i++) // loop-1
{
x=rand()%512;
bitset<9> bitseq(x);
if( prev != -1 ) // don't check this on the first iteration
{
bool cur = bitseq.test(0);
if( !prev && !cur )
++transition0_0;
else if( !prev && cur )
++transition0_1;
else if( prev && !cur )
++transition1_0;
else
++transition1_1;
}
for(int j=0;j+1<bitseq.size();j++) // loop-2
{
bool a= bitseq.test(j);
bool b= bitseq.test(j+1)
if ((a==0)&&(b==0))
{
transition0_0 = transition0_0 + 1; // transition from 0 to 0
}
else if ((a==0)&&(b==1))
{
transition0_1 = transition0_1 + 1;
}
else if ((a==1)&&(b==0))
{
transition1_0 = transition1_0 + 1;
}
else
{
++transition1_1 = transition1_1 + 1;
}
} // for-2
prev = bitseq.test(bitseq.size()-1); // update prev for the next iteration
cout<<transition0_0<<" "<<transition0_1<<endl;
cout<<transition1_0<<" "<<transition1_1<<endl;
} // for-1
} // main
Would something like this be better for you? Use an array of 4 ints where [0] = 0->0, [1] = 0->1, [2] = 1->0, [3] = 1->1.
int main {
int nTransition[] = { 0,0,0,0 };
bool a,b;
unsigned int x;
int j;
srand ((unsigned)time(0));
for (int i = 0: i < 512; i++) {
x = rand () % 512;
bitset<9> bitseq(x);
if (i == 0) {
a = bitseq.test (0);
j = 1;
} else
j = 0;
for (; j < bitseq.size (); j++) {
b = bitseq.test(j);
int nPos = (a) ? ((b) ? 3 : 2) : ((b) ? 1 : 0);
nTransition[nPos]++;
a = b;
}
}
}
I wrote a program to calculate (adding) 2 positive big integer using vector to store the numbers.
#include <cstdlib>
#include <cstdio> // sd sprintf()
#include <iostream>
#include <vector>// sd vector
typedef short TYPE;// alias
void input();
void makeArray();
void display(const std::vector<TYPE> Ar);
TYPE convertChar2T( char * ch);
void add();
static std::string num1;//store big integer as string
static std::string num2;
static std::vector<TYPE> Arr1;//store as vector
static std::vector<TYPE> Arr2;
static std::vector<TYPE> result;
int main(int argc, char** argv) {
input();
makeArray();
display(Arr1);
display(Arr2);
add();
display(result);
return 0;
}
//input 2 big integer number
void input(){
std::cout << "Enter 1st number : " ;
if (! std::getline(std::cin , num1) )
std::cerr << "Not OK\n";
std::cout << "Enter 2nd number : ";
if (! std::getline(std::cin , num2) )
std::cerr << "Not OK\n";
}
//grab into 2 arrays
void makeArray(){
for (std::size_t i = 0; i < num1.size(); i++){
char temp1[2] = { num1[i], '\0'}; //use array-of-char as it need '\0'
Arr1.push_back( convertChar2T(temp1) ); //push what is converted
}
for (std::size_t i = 0; i < num2.size(); i++){
char temp2[2] = { num2[i], '\0'};
Arr2.push_back( convertChar2T(temp2) );
}
}
//convert char -> TYPE by using sscanf()
TYPE convertChar2T( char * ch){
TYPE numb ;
sscanf( ch, "%d", &numb );//NGUOC LAI SPRINTF
return numb;
}
//display array
void display(const std::vector<TYPE> Ar){
for (std::size_t i = 0; i < Ar.size(); i++)
std::cout << Ar.at(i) << '\t';
std::cout << '\n';
}
void add(){
std::size_t i = Arr1.size(); // NEVER COMES TO ZERO ( 1 AT LEAST )
std::size_t j = Arr2.size();
//check original one and later one
//3 cases : 1 - original one , not yet processed
// 2 - original # one, not yet processed
// -1 - original # one or one, processed
//NOTE: at first only value 1 or 2 ( not process )
short check_one[2] = {
( i == 1 ) ? 1 : 2,
( j == 1 ) ? 1 : 2,
};
bool boost = 0;
bool Arr1_isgood = true;// whether count to 1 or not
bool Arr2_isgood = true;// good -> not yet 1
short temp_result = 0;//temporary result to push into vector
while ( Arr1_isgood || Arr2_isgood ){// while not all comes to 1
// i == j : 2 cases
// 1st: both 1 now - 3 cases
// 1.1 #1+not process original and processed
// 1.2 processed and #1+not processed
// 1.3 both 1 original + not processed
// 2nd: both # 1
if ( i == j ) {
if ( check_one[0] == 2 && check_one[1] == -1 ){//#1+not process original and processed
temp_result = Arr1[i-1] + boost;
check_one[0] == -1;
}
else if ( check_one[0] == -1 && check_one[1] == 2 ){//processed and #1+not processed
temp_result = Arr2[j-1] + boost;
check_one[1] = -1;
}
else//both 1 original + not processed OR both # 1
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
//check result >= 10 or < 10
if ( temp_result >= 10 ){
temp_result = temp_result - 10 ;
boost = 1;
}
else
boost = 0;
//result.begin() return iterator at beginning
result.insert( result.begin() ,temp_result );
//update info
if ( i == j && i == 1){ // NOTE : NEU SD i==j==1 -> sai (vi luon true)
Arr1_isgood = Arr2_isgood = false;
continue;
}
else if ( i == j && i != 1){ // i == j # 1
i--;
j--;
}
}
if (i != j){
//check to set flag ( if one of two die )
if ( i == 1 && j > 1 )
Arr1_isgood = false;
else if ( i > 1 && j == 1 )
Arr2_isgood = false;
// i die && j live OR vice versa
if ( (!Arr1_isgood && Arr2_isgood) ||
(Arr1_isgood && !Arr2_isgood ) ){
if (!Arr1_isgood && Arr2_isgood ){ //1st case
if ( check_one[0] == 1 || check_one[0] == 2){//not yet processed as SET FLAG ABOVE first
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
check_one[0] = -1 ;
}
else
temp_result = Arr2[j-1] + boost;
j--;
}
else if ( Arr1_isgood && !Arr2_isgood ){ //2nd case
if ( check_one[1] == 1 || check_one[1] == 2 ){//not yet processed as SET FLAG ABOVE first
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
check_one[1] = -1 ;
}
else
temp_result = Arr1[i-1] + boost;
i--;
}
}
else {// both is good
temp_result = Arr1[i-1] + Arr2[j-1] + boost;
i--;
j--;
}
//check result >= 10 or < 10
if (temp_result >= 10) {
temp_result -= 10;
boost = 1;
} else
boost = 0;
result.insert( result.begin() ,temp_result );
}
}
//insert boost (if any exists)
if (boost == 1)
result.insert( result.begin(), boost);
}
I'm torn between the use of "Arr1_isgood" bool variable and the check_one variable, it seems that they can be combined into one variable ? I tried to do it and it takes a lot of time without correct result.
Can the digit be store in some kind of smaller data structure rather than "short" type ? as "short" takes more than needed bits.
Another thing is : it seems that std::size_t only reach up to 4 billion in size, as when size_t reach 1, I decreased it several times and it comes to 4 billion ? Isn't it?
I wonder if these codes somehow can be optimized more?
If you want to manipulate big integers, you should use a big-integer library, e.g. GMP.
In your machine has 32-bit ints, suppose you represent each number (unsigned) as an array of 31-bit signed ints, starting from the least significant.
Then maybe you could do something like this:
// do c = a + b
int a[n], b[n], c[n];
int carry = 0;
for (i = 0; i < n; i++){
// do the addition with carry
c[i] = a[i] + b[i] + carry;
// if the addition carried into the sign bit
carry = (c[i] < 0);
// detect it and remove it from the sum
if (carry){
c[i] &= 0x7fffffff;
}
}
Then you could figure out how to handle negatives.
I got a bit stuck with my algorithm and I need some help to solve my problem. I think an example would explain better my problem.
Assuming:
d = 4 (maximum number of allowed bits in a number, 2^4-1=15).
m_max = 1 (maximum number of allowed bits mismatches).
kappa = (maximum number of elements to find for a given d and m, where m in m_max)
The main idea is for a given number, x, to compute its complement number (in binary base) and all the possible combinations for up to m_max mismatches from x complement's number.
Now the program start to scan from i = 0 till 15.
for i = 0 and m = 0, kappa = \binom{d}{0} = 1 (this called a perfect match)
possible combinations in bits, is only 1111 (for 0: 0000).
for i = 0 and m = 1, kappa = \binom{d}{1} = 4 (one mismatch)
possible combinations in bits are: 1000, 0100, 0010 and 0001
My problem was to generalize it to general d and m. I wrote the following code:
#include <stdlib.h>
#include <iomanip>
#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <stdint.h>
#include <vector>
namespace vec {
typedef std::vector<unsigned int> uint_1d_vec_t;
}
int main( int argc, char* argv[] ) {
int counter, d, m;
unsigned num_combination, bits_mask, bit_mask, max_num_mismatch;
uint_1d_vec_t kappa;
d = 4;
m = 2;
bits_mask = 2^num_bits - 1;
for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
counter = 0;
for ( unsigned m = 0 ; m < max_num_mismatch ; m++ ) {
// maximum number of allowed combinations
num_combination = boost::math::binomial_coefficient<double>( static_cast<unsigned>( d ), static_cast<unsigned>(m) );
kappa.push_back( num_combination );
for ( unsigned j = 0 ; j < kappa.at(m) ; j++ ) {
if ( m == 0 )
v[i][counter++] = i^bits_mask; // M_0
else {
bit_mask = 1 << ( num_bits - j );
v[i][counter++] = v[i][0] ^ bits_mask
}
}
}
}
return 0;
}
I got stuck in the line v[i][counter++] = v[i][0] ^ bits_mask since I was unable to generalize my algorithm to m_max>1, since I needed for m_max mismatches m_max loops and in my original problem, m is unknown until runtime.
i wrote a code that do what i want, but since i am newbie, it is a bit ugly.
i fixed m and d although this code would work fine for genral m and d.
the main idea is simple, assuming we would like to compute the complement of 0 up to two failure (d= 4,m=2), we will see that max number of possibilities is given by \sum_{i = 0)^2\binom{4}{i} = 11.
The complement to 0 (at 4 bits) is 15
With 1 bit possible mismatch (from 15): 7 11 13 14
with 2 bits possible mismatches (from 15): 3 5 6 9 10 12
i wanted that the output of this program will be a vector with the numbers 15 7 11 13 14 3 5 6 9 10 12 inside it.
i hope that this time i am more clear with presenting my question (although i also supplied the solution). I would appreachiate if someone could point out, in my code, ways to improve it and make it faster.
regards
#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <vector>
#define USE_VECTOR
namespace vec {
#if defined(USE_VECTOR) || !defined(USE_DEQUE)
typedef std::vector<unsigned int> uint_1d_vec_t;
typedef std::vector<uint_1d_vec_t> uint_2d_vec_t;
#else
typedef std::deque<unsigned int> uint_1d_vec_t;
typedef std::deque<uint_1d_vec_t> uint_2d_vec_t;
#endif
}
using namespace std;
void get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned max_num_unmatch , unsigned num_bits );
double get_kappa( int m , int d );
int main( ) {
unsigned int num_elements , m , num_bits;
num_elements = 16;
num_bits = 4; // 2^4 = 16
m = 2;
double kappa = 0;
for ( unsigned int i = 0 ; i <= m ; i++ )
kappa += get_kappa( num_bits , i );
vec::uint_2d_vec_t Pointer( num_elements , vec::uint_1d_vec_t (kappa ,0 ) );
get_pointers_vec( Pointer , num_elements , m , num_bits );
for ( unsigned int i = 0 ; i < num_elements ; i++ ) {
std::cout << setw(2) << i << ":";
for ( unsigned int j = 0 ; j < kappa ; j++ )
std::cout << setw(3) << Pointer[i][j];
std::cout << std::endl;
}
return EXIT_SUCCESS;
}
double get_kappa( int n , int k ) {
double kappa = boost::math::binomial_coefficient<double>( static_cast<unsigned>( n ), static_cast<unsigned>(k) );
return kappa;
}
void get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned max_num_unmatch , unsigned num_bits ) {
int counter;
unsigned num_combination, ref_index, bits_mask, bit_mask;
vec::uint_1d_vec_t kappa;
bits_mask = pow( 2 , num_bits ) - 1;
for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
counter = 0;
kappa.clear();
ref_index = 0;
for ( unsigned m = 0 ; m <= max_num_unmatch ; m++ ) {
num_combination = get_kappa( num_bits , m ); // maximum number of allowed combinations
kappa.push_back( num_combination );
if ( m == 0 ) {
v[i][counter++] = i^bits_mask; // M_0
}
else if ( num_bits == kappa.at(m) ) {
for ( unsigned k = m ; k <= num_bits ; k++ ) {
bit_mask = 1 << ( num_bits - k );
v[i][counter++] = v[i][ref_index] ^ bit_mask;
}
}
else {
// Find first element's index
ref_index += kappa.at( m - 2 );
for( unsigned j = 0 ; j < ( kappa.at(m - 1) - 1 ) ; j++ ) {
for ( unsigned k = m + j ; k <= num_bits ; k++ ) {
bit_mask = 1 << ( num_bits - k );
v[i][counter++] = v[i][ref_index] ^ bit_mask;
}
ref_index++;
}
}
}
}
}