I was trying to come up with the solution for that ... two large numbers, a and b are represented by char[] or char* and the goal is to multiply them into a third pointer, char* c:
void multiply( const char* a, const char* b ){
int len_a = strlen( a );
int len_b = strlen( b );
int* c = new int[ len_a + len_b];
memset( c, 0, sizeof(int) * ( len_a + len_b ));
for( int i = len_a - 1; i >= 0; i-- ){
for( int j = len_b - 1; j >= 0; j-- ){
c[ i + j + 1 ] += ( b[ j ] - '0') * ( a[ i ] - '0' );
}
}
for( int i = len_a + len_b; i >= 0; i-- ){
if( c[ i ] >= 10 ){
c[ i - 1 ] += c[ i ] / 10;
c[ i ] %= 10;
}
}
cout << a << " * " << b << " = " << c << endl;
delete[] c;
}
I wrote the above function to do this operation for me ... however, when I use the inputs:
int main( void ){
const char* a = "999";
const char* b = "99999";
multiply( a, b );
// I expect the answer to be 1 and 6
// profit = 0.92
return 0;
}
I got:
999 * 99999 = 0x100100080
Why am I getting the memory address and not the actual number?
Thanks!
Because c is an int pointer and the stream operator for cout will print a memory address if passed such a pointer. To get the value you need to dereference the pointers with e.g. *c. You'll probably need to write a loop to print the whole "string" of integers.
cout << a << " * " << b << " = ";
for( int i = 0; i < len_a + len_b; i++ ){
cout << c[ i ];
}
cout << endl;
will yield the desired result ...
Your logic is correct.
Just a quick reminder: When you create an integer pointer and want to use it as an array, it points to "the first element of the array" therefore when you print it, you see the address of the first element of the array c, which is "0x100100080" in your case.
To print the number (characters) stored in c you need to de-reference the pointer, i.e., print the elements in the array one after another. Or alternatively you can convert your array into a number and print it at once. For the latter, please refer to: How to convert array of integers into an integer in C?.
For printing the characters one by one you could replace
std::cout<<c;
with the following code:
int n=strlen(c);
for(int i=0; i<n; i++) {
std::cout<<c[i];
}
This will print the number.
std::ostream (of which type std::cout is) doesn't have any overloaded operators specifically for int*, thus it falls back to the void* overload which simply outputs the pointer value in an implementation-defined manner.
Furthermore, it wouldn't be possible for an int* overload to determine that the pointer points to an array, and further still, how many elements such an array would have.
for(c++14)
we can use boost libarary..
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
int main()
{
mp::cpp_int s1("12368123681263817263863821638126328136218362182");
mp::cpp_int s2("345897937325785470923092923709887329092470423707534025");
mp::cpp_int S=s1*s2;
std::cout << S << '\n';
}
Related
I have a problem. I want from a given number to get each digit as an element in the same array.
But when I compile, if I extend the range from one iteration above the size of the given number, I get a corrupted data exception from Visual Studio in Debug mode as an exception.
I thought first that was because the int type is only 4 digit max length as a 4 bytes entity because I used to get only one digit for greater number above 9999. But I noticed that my number starts at an iteration value one too late...which makes it impossible to show the last digit.
If I add a zero to my given number, I can manually offset in the opposite direction, but that doesn't work with my original number.
But, I can't find out how to fix that...Here is my code.
Before asking for help, here is a screenshot explaining the principle which is used to convert the number into an array: math theory formula
I wish to solve it with the number type only because the char type involves another way managing the memory with buffers...which I don't really know how to handle right know.
Can someone help me to complete the debugging please ?
#include <iostream>
#include <math.h>
//method to convert user number entry to array of digits
long long numToArray(double num,double arrDigits[], const long long n) {
//instanciate variables
//array of with m elements
arrDigits[n];
double* loopValue = new double(0);
//extract the digits and store them into arrDigits array
for (long long i = 0; i < n; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0);
*loopValue = floor(num / pow(10, n - i)) - temp;
arrDigits[i] = *loopValue;
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
return 0;
}
//main program interacting with the user
int main()
{
std::cout << "please type an integer: ";
double num;
const long long n = sizeof(num);
double array[n]{};
std::cin >> num;
//call the method to test if all values are in the array
numToArray(num, array, n);
return 0;
}
Explaining the troubleshoot
Note : Visual Studio shows error if I extend from n to n+1. If I let the type int or long, sizeof(num) is all the time 4...
Then, I had to set it as double and to extract it from the main scope, which makes it ...double...
People asking to remove pointer, it is impossible to run the program if I do so.
I want from a given number to get each digit as an element in the same array.
If you want to simply get each number into an array, it takes only a few lines of code to convert the decimal to a string, remove the decimal point (if it exists), and then copy the string to a buffer:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iomanip>
int main()
{
double d = 1.45624234;
std::ostringstream strm;
strm << std::setprecision(12);
// copy this to a string using the output stream
strm << d;
std::string s = strm.str();
// remove the decimal point
s.erase(std::remove(s.begin(), s.end(), '.'), s.end());
// Now copy each digit to a buffer (in this case, vector)
std::vector<int> v;
std::transform(s.begin(), s.end(), std::back_inserter(v), [&](char ch) { return ch - '0';});
// output the results
for (auto c : v )
std::cout << c;
}
Output:
145624234
All of the work you were doing is already done for you by the standard library. In this case the overloaded operator << for double when streamed to a buffer creates the string. How it does it? That is basically what your code is attempting to do, but obviously safely and correctly.
Then it's just a matter of transforming each digit character into an actual integer that represents that digit, and that is what std::transform does. Each digit character is copied to the vector by subtracting the character 0 from each char digit.
#include <iostream>
#include <math.h>
#include <list>
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
//counting the number of digits
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum/10;
++count;
}
std::cout << "number of digits compositing your natural integer: " << count<<std::endl;
//process the value for conversion to list of digits, so you can
//access each digits by power and enhance your calculus operations
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - count;//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
//print the converted list
std::cout << "array converted to list: ";
for (double j : listDigits) {
std::cout << j << " ";
}
std::cout << std::endl;
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
std::cout << "removed zero element to the list\n";
for (double i : listDigits) {
std::cout << i << " ";
}
std::cout << "natural integer successfully converted into list digits data\n";
return 0;
}
an example on debug mode in Visual Studio 2019
I finally encapsulated the whole code into two functions. But I have an extra value at first and last iteration...
The answer is almost complete, just need to solve the offset from inside the main moved to it's owned function. I finally added a new array variable with the exact size I want from the two new functions, so we get the array which will be possible to manipulate so far away.
#include <iostream>
#include <math.h>
#include <list>
int CountNumberDigits(int num) {
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum / 10;
++count;
}
return count;
}
double* NumToArray(double num) {
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - CountNumberDigits(num);//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
for (double j : listDigits) {
std::cout << j << " ";
}
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
//convert list to array
double* arrOutput = new double[listDigits.size()]{};
std::copy(listDigits.begin(), listDigits.end(), arrOutput);
double* ptrResult = arrOutput;
return ptrResult;
}
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
int count = CountNumberDigits(num);
std::cout << "number of digits compositing your natural integer: " << count << std::endl;
double* ptrOutput = NumToArray(num);
//reduce the array to the num size
double* shrinkArray = new double[CountNumberDigits(num)];
for (int i = 0; i < CountNumberDigits(num); i++) {
*(shrinkArray+i) = ptrOutput[i];
std::cout << *(shrinkArray+i) << " ";
}
#include <bits/stdc++.h>
using namespace std;
/*Prototype for utility functions */
void printArray(int arr[], int size);
void swap(int arr[], int fi, int si, int d);
void leftRotate(int arr[], int d, int n)
{
/* Return If number of elements to be rotated
is zero or equal to array size */
if(d == 0 || d == n)
return;
/*If number of elements to be rotated
is exactly half of array size */
if(n - d == d)
{
swap(arr, 0, n - d, d);
return;
}
/* If A is shorter*/
if(d < n - d)
{
swap(arr, 0, n - d, d);
leftRotate(arr, d, n - d);
}
else /* If B is shorter*/
{
swap(arr, 0, d, n - d);
leftRotate(arr + n - d, 2 * d - n, d); /*This is tricky*/
}
}
/*UTILITY FUNCTIONS*/
/* function to print an array */
void printArray(int arr[], int size)
{
int i;
for(i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
/*This function swaps d elements starting at index fi
with d elements starting at index si */
void swap(int arr[], int fi, int si, int d)
{
int i, temp;
for(i = 0; i < d; i++)
{
temp = arr[fi + i];
arr[fi + i] = arr[si + i];
arr[si + i] = temp;
}
}
// Driver Code
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7};
leftRotate(arr, 2, 7);
printArray(arr, 7);
return 0;
}
// This code is contributed by Rath Bhupendra
I found this code on the geek for geeks website. The code is used to rotate the elements of an array. It is mentioned as block swap algorithm in the website, my questions are:
Can we add integers to an array in c++ as given in the else part of the left rotate function while passing the arguments (arr+n-d)?
How can we add integers to an array?
I tried adding an integer to an array in an online compiler and it didn't work. But the above code works perfectly giving the desired output 34567.
The link to the website is https://www.geeksforgeeks.org/block-swap-algorithm-for-array-rotation/.
Can we add integers to an array in c++ as given in the else part of the left rotate function while passing the arguments (arr+n-d)?
How can we add integers to an array?
The answer is you can't, and that's not what's happening here.
int arr[] argument decays to a pointer to the first element of the array. It's the same as having int* arr so what you are doing in arr + n - d is simple pointer arithmetic.
The pointer will be moved n - d positions relative to the position it's at before the expression is evaluated.
Supposing the result of n - d is 4, and arr is pointing to the beginning of the array passed as an argument, that is to &arr[0] (in array notation) or arr + 0 (in pointer notation), which is where it's pointing to in its inicial state, you'll have arr + 4 or &arr[4], after the evaluation, the expression provides access to the address of index 4 (the 5th element of the array). To access the value within that address you'd use *(arr + 4) or arr[4].
On a side note I wouldn't advise the use of geeksforgeeks.com to learn C++, or any other language, for that matter, this should be done by reading a good book.
A function parameter having an array type is adjusted by the compiler to pointer to the array element type. That is these two function declarations are equivalent and declare the same one function.
void leftRotate(int arr[], int d, int n);
and
void leftRotate(int *arr, int d, int n);
You even may write for example
void leftRotate(int arr[100], int d, int n);
void leftRotate(int arr[10], int d, int n);
void leftRotate(int arr[1], int d, int n);
Again these declarations declare the function
void leftRotate(int *arr, int d, int n);
So within the function this expression
arr + n - d
uses the pointer arithmetic applied to the pointer arr.
For example the expression arr + 0 is equivalent to arr and points to the first element of the array. The expression arr + n points to the n-th element of the array.
Here is a demonstrative program where there is used the pointer arithmetic to output elements of an array in a loop.
#include <iostream>
int main()
{
int a[] = { 1, 2, 3, 4, 5 };
for ( size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++ )
{
std::cout << *( a + i ) << ' ';
}
std::cout << '\n';
return 0;
}
The program output is
1 2 3 4 5
In the expression *( a + i ) the array designator a is implicitly converted to pointer to its first element.
Here is one more demonstrative program that shows that a function parameter having an array type is adjusted by the compiler to pointer to the array element type.
#include <iostream>
#include <iomanip>
#include <type_traits>
const size_t N = 100;
void f( int a[N] )
{
std::cout << "\nin function\n";
std::cout << "sizeof( a ) = " << sizeof( a ) << '\n';
std::cout << "a is a pointer " << std::boolalpha <<std:: is_same<decltype( a ), int *>::value << '\n';
}
int main()
{
int a[N];
std::cout << "In main\n";
std::cout << "sizeof( a ) = " << sizeof( a ) << '\n';
std::cout << "a is an array " << std::boolalpha <<std:: is_same<decltype( a ), int [N]>::value << '\n';
f( a );
return 0;
}
The program output is
In main
sizeof( a ) = 400
a is an array true
in function
sizeof( a ) = 8
a is a pointer true
The following code (in C++) is supposed to get some data along with it's size (in terms of bytes) and return the string containing the hexadecimal code. size is the size of the memory block with its location stored in val.
std::string byteToHexString(const unsigned char* val, unsigned long long size)
{
unsigned char temp;
std::string vf;
vf.resize(2 * size+1);
for(unsigned long long i= 0; i < size; i++)
{
temp = val[i] / 16;
vf[2*i] = (temp <= 9)? '0' + temp: 'A' + temp - 10; // i.e., (10 = 9 + 1)
temp = val[i] % 16;
vf[2*i+1] = (temp <= 9)? '0' + temp: 'A' + temp - 10; // i.e., (10 = 9 + 1)
}
vf[2*size] = '\0';
return (vf);
}
So on executing the above function the following way:
int main()
{
unsigned int a = 5555;
std::cout << byteToHexString((unsigned char*)(&a), 4);
return 0;
}
The output we obtain is:
B3150000
Shouldn't the output rather be 000015B3? So why is this displaying in reverse order? Is there something wrong with the code (I am using g++ compiler in Ubuntu)?
You are seeing the order in which bytes are stored for representing integers on your architecture, which happens to be little-endian. That means, the least-significant byte comes first.
If you want to display it in normal numeric form, you either need to detect the endianness of your architecture and switch the code accordingly, or just use a string stream:
unsigned int a = 5555;
std::ostringstream ss;
ss << std::setfill( '0' ) << std::setw( sizeof(a)*2 ) << std::hex << a;
std::cout << ss.str() << std::endl;
I'm having some trouble with this non recursive Fibonacci function. I am using this array of numbers and passing it to FiboNR, however I am getting large negative values and Access Violation errors.
int n[15] = { 1,5,10,15,20,25,30,35,40,45,50,55,60,65,70 };
int FiboNR(int n) // array of size n
{
int const max = 100;
int F[max];
F[0] = 0; F[1] = 1;
for (int i = 2; i <= n; i++) {
F[n] = F[n - 1] + F[n - 2];
}
return (F[n]);
}
The function was one provided by the instructor and I assume its correct if he's giving it out but with these memory errors I don't fully understand what's going on. The only way I'm calling the in a loop to go through the array and outputting the answer like cout << FiboNR(n[i]);
First of all, your trouble is in loop. Replace:
F[n] = F[n - 1] + F[n - 2];
with:
F[i] = F[i - 1] + F[i - 2];
Because i is your iterator and n is only the limit.
Just FYI, the braces ( ) in return statement are not needed, you can ignore them.
I am using this array of numbers and passing it to FiboNR
You are not supposed to do that since FiboNR() excepts its argument to be an integer (one, not an array of integers). So you should pass only one number to your function, like: FiboNR(n[2]).
You get a negative numbers due to int overflow for int array (n > 46).
Change array type from int to long long.
Other solutions: change array type to float/double type with less precision of the results or use long arithmetic.
Type | Typical Bit Width | Typical Range
int | 4bytes| -2147483648 to 2147483647
Link: C++ Data Types
Example of code below.
#include <iostream>
long long FiboNR(int n);
long long FiboNR(int n) {
int const max = 100;
long long F[max];
if (n > max) {
n = max;
}
F[0] = 0;
F[1] = 1;
for (int i = 2; i <= n; i++){
F[i] = F[i - 1] + F[i - 2];
}
return (F[n]);
}
int main() {
for (int i=0; i < 100; i++) {
std::cout << "i = " << i << " : " << FiboNR(i) << std::endl;
}
return 0;
}
The following C++ code (as is) is from http://rosettacode.org/wiki/Entropy. There are mistakes - can anyone correct them?
#include <string>
#include <map>
#include <iostream>
#include <algorithm>
#include <cmath>
double log2( double number ) {
return log( number ) / log( 2 ) ;
}
int main( int argc , char *argv[ ] ) {
std::string teststring( argv[ 1 ] ) ;
std::map<char , int> frequencies ;
for ( char c : teststring )
frequencies[ c ] ++ ;
int numlen = teststring.length( ) ;
double infocontent = 0 ;
for ( std::pair<char , int> p : frequencies ) {
double freq = static_cast<double>( p.second ) / numlen ;
infocontent += freq * log2( freq ) ;
}
infocontent *= -1 ;
std::cout << "The information content of " << teststring
<< " is " << infocontent << " !\n" ;
return 0 ;
}
The first error seems to be fixed with:
double log2( double n )
{
// log(n)/log(2) is log2.
return log( n ) / log( 2. );
}
I'm unsure what they are trying to say with:
for ( char c : teststring )
This one work nice
template <typename T> static float ShannonEntropy(T data[],int elements){
float entropy=0;
std::map<T,long> counts;
typename std::map<T,long>::iterator it;
//
for (int dataIndex = 0; dataIndex < elements; ++dataIndex) {
counts[data[dataIndex]]++;
}
//
it = counts.begin();
while(it != counts.end()){
float p_x = (float)it->second/elements;
if (p_x>0) entropy-=p_x*log(p_x)/log(2);
it++;
}
return entropy;
}
The loop is a foreach loop. It means: For each character in teststring, put it into the variable c and do the loop body.
The same can be expressed with a regular for-loop and an index variable, but this way is much shorter and easier to read. Other languages like C# and Java had this for a long time, but C++ only had some template feature in the STL that were not as readable.
This is a new feature of C++ 11 and your compiler will complain if it's not compatible. If you get errors, try to get a better compiler.
Here is my java code for entropy of image
public static double getShannonEntropy_Image(BufferedImage actualImage){
List<String> values= new ArrayList<String>();
int n = 0;
Map<Integer, Integer> occ = new HashMap<>();
for(int i=0;i<actualImage.getHeight();i++){
for(int j=0;j<actualImage.getWidth();j++){
int pixel = actualImage.getRGB(j, i);
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
//0.2989 * R + 0.5870 * G + 0.1140 * B greyscale conversion
//System.out.println("i="+i+" j="+j+" argb: " + alpha + ", " + red + ", " + green + ", " + blue);
int d= (int)Math.round(0.2989 * red + 0.5870 * green + 0.1140 * blue);
if(!values.contains(String.valueOf(d)))
values.add(String.valueOf(d));
if (occ.containsKey(d)) {
occ.put(d, occ.get(d) + 1);
} else {
occ.put(d, 1);
}
++n;
}
}
double e = 0.0;
for (Map.Entry<Integer, Integer> entry : occ.entrySet()) {
int cx = entry.getKey();
double p = (double) entry.getValue() / n;
e += p * log2(p);
}
return -e;
}
The first error is because of the fiasco regarding names from the C library. It's not specified which overloads of log are dumped into the global namespace; presumably, the author's implementation only had one, so that log(2) is unambiguous, but yours has all of them, giving an ambiguity since there isn't one that takes type int. For portability, it should be std::log(2.). Better still, use std::log2 rather than reinventing it.
The second is a "range-based for statement", introduced to the language in 2011, which iterates over each element of an array, container, or other sequence. You'll need a reasonably modern compiler, and you may need to specifically enable C++11 support. For example, with GCC, you need the command-line argument -std=c++11 (or c++0x with older versions).
The above generic answer is very good, but for the particular case of strings, this one is simpler:
#include <cmath>
#include <string>
float shannon_entropy(const std::string & s)
{
int counts[256] = {};
for (unsigned char c: s)
{
counts[c]++;
}
float entropy = 0;
float length = (float)s.size();
for (int count: counts)
{
if (count == 0)
continue;
float p = (float)count / length;
entropy -= p * std::log2f(p);
}
return entropy;
}