Adding two integer array elements
if array1 = {0,0,0,0,9,9,9,9}—————> 00009999
and
array2 = {0,0,0,0,0,0,0,1}————————> 00000001
adding the two arrays together should result in 10000 being in array1, since 9999 + 1 = 10000
therefore, the result should be
array1 = {0,0,0,1,0,0,0,0}
Does anyone know how to write a code for this? I was trying to use a while loop which didn't work effectively within another for loop. Fairly new to coding and stack overflow, any help will be appreciated!
CODE THAT I TRIED
Note: both arrays will have the same number of elements, they were initialized with the same size
int length = sizeof(array1)/sizeof(array1[0]);
for(int i = length; i>0; i--){
if(array1[i-1] + array2[i-1] < 10){
array1[i-1] += array2[i-1];
}else{
array1[i-1] = array1[i-1] + array2[i-1] - 10;
if(array1[i-2]!=9){
array1[i-2]++;
} else{
int j = i-2;
while(j == 9){
array1[j] = 0;
j--;
}
array1[j-1]++;
}
}
}
Code below performs base10 arithmetic: you need to iterate the arrays in reverse, do the addition of i-th digit by modulo 10, then carry over any excess digits to the next array element:
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
int a1[] = { 0,0,0,0,9,9,9,9 };
int a2[] = { 0,0,0,0,0,0,0,1 };
const int b = 10;
int s = 0;
for (int i = size(a1) - 1; i >= 0; --i)
{
a1[i] += a2[i] + s;
s = a1[i] / b;
a1[i] %= b;
}
std::copy(a1, a1 + size(a1), ostream_iterator<int>(cout, " "));
cout << endl;
}
Alternative with C arrays and transform algorithm + make_reverse_iterator looks too heavy. Variant with std::arrays looks better:
#include <algorithm>
#include <array>
#include <iterator>
#include <iostream>
using namespace std;
int main()
{
std::array<int, 8> a1 = { 0,0,0,0,9,9,9,9 };
std::array<int, 8> a2 = { 0,0,0,0,0,0,0,1 };
const int b = 10;
int s = 0;
transform(a1.rbegin(), a1.rend(), a2.rbegin(), a1.rbegin(), [b, &s](int &i, int &j)
{
i += j + s;
s = i / b;
return i % b;
});
copy(a1.begin(), a1.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
It looks like you've overcomplicated the problem a bit. Your task is to perform base 10 addition on two arrays, carrying excess digits. You can simply iterate both arrays in reverse, perform addition on the individual elements, and ensure you carry over a digit when you exceed 10.
Here is an example based on the requirements you've described. You can further abstract this as needed.
I updated this code such that the result is now in array1.
#include <iostream>
int main(int argc, char *argv[], char *argp[]){
/* Initialize arrays and calculate array size */
int array1[] = {0,0,0,0,9,9,9,9};
int array2[] = {0,0,0,0,0,0,0,1};
int array_size = sizeof(array1) / sizeof(int);
/* Iterate the arrays in reverse */
int carry = 0;
for (int i = array_size - 1; i >= 0; i--) {
/* Perform addition on the current elements, remembering to include the carry digit */
int result = array1[i] + array2[i] + carry;
/* Determine if the addition should result in another carry */
if (result >= 10) {
carry = 1;
} else {
carry = 0;
}
/* Store the non-carried addition result */
array1[i] = result % 10;
}
/* View result */
for (int i = 0; i < array_size; i++) {
std::cout << array1[i];
}
std::cout << std::endl;
return 0;
}
uint32_t decode(int array[8]){
uint32_t multiple_of_ten=10000000;
uint32_t result = 0;
for(int i=0;i<8;i++){
result += (array[i] * multiple_of_ten);
multiple_of_ten = multiple_of_ten / 10;
}
return result;
}
int* encode(uint32_t number){
int result[8]={0,0,0,0,0,0,0,0};
uint32_t multiple_of_ten=10000000;
uint32_t recent = number;
for(int i=0;i<8;i++){
if(recent>0 && recent / multiple_of_ten > 0)
{
result[i] = recent / multiple_of_ten;
recent %= multiple_of_ten;
}
multiple_of_ten /= 10;
}
return result;
}
in your case , use encode(decode(array1) + decode(array2))
Related
I am trying to delete any duplicates but not having much success..
void deleatingRepeatingElement (int myArrayLength, int myArray[])
{
for (int i = 1 ; i < myArrayLength; i++){
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i ; j++){
if (myArray[i] == myArray[j]){
myArray[j] = myArray[j + 1];
myArrayLength--;
}
}
}
}
I think there were two main mistakes:
You didn't shift all of the following items when deleting.
You didn't "reset" after deleting.
Here is annotated code that seems to work:
#include <iostream>
/* Remove element at given index from array
* Returns the new array length
* (Note that "int array[]" means exactly the same as "int *array",
* so some people would consider "int *array" better style)
*/
int arrayRemoveAt(int index, int array[], int arrayLength)
{
// Check whether index is in range
if (index < 0 || index >= arrayLength)
return arrayLength;
for (int i = index + 1; i < arrayLength; i++)
{
array[i - 1] = array[i];
}
return arrayLength - 1;
}
/*
* Returns the new length of the array
*/
int deleatingRepeatingElement(int myArrayLength, int myArray[])
{
for (int i = 1; i < myArrayLength; i++)
{
// start at second index because you don't need to compare the first element to anything, it can't have duplicate that comes first
for (int j = 0; j < i; j++)
{
if (myArray[i] == myArray[j])
{
myArrayLength = arrayRemoveAt(i, myArray, myArrayLength);
// After deleting an entry, we must "reset", because now the index i
// might point to another number, which may be a duplicate
// of a number even before the current j.
// The i-- is so that after i++, we will end up with the same i
i--;
break;
}
}
}
// Important: The caller needs this for looping over the array
return myArrayLength;
}
int main(int argc, char **argv)
{
int array[] = {5, 6, 2, 1, 2, 6, 6};
int newSize = deleatingRepeatingElement(7, array);
for (int i = 0; i < newSize; i++)
{
std::cout << array[i] << std::endl;
}
return 0;
}
If you use a static array (such as in my example, as opposed to a dynamic one), you may consider using std::array or a template construction as shown in https://stackoverflow.com/a/31346972/5420386.
Here is the solution to your problem:
#include <iostream>
#include <set>
#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))
using namespace std;
int *deleteRepeatedElements(int myArray[], int arrayLength) {
set<int> setArray (myArray, myArray+arrayLength);
int setLength = setArray.size();
static int myPointer[4];
int i = 0;
for (set<int>::iterator it = setArray.begin(); it != setArray.end(); ++it) {
myPointer[i] = *it;
i++;
}
return myPointer;
}
int main() {
int myArray[6] = {5, 3, 5, 6, 2, 4};
int arrayLength = ARRAY_SIZE(myArray);
int* myPointer = deleteRepeatedElements(myArray, arrayLength);
int pointerLength = sizeof(myPointer)/sizeof(*myPointer);
for (int* i = &myPointer[0]; *myPointer != 0; i = ++myPointer) {
cout << *i << " ";
}
cout << '\n';
return 0;
}
How can I finish my code to take an integer array (arr[]), its length (N), and the number of elements to right-shift (M).
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void shiftright (int myarray[], int size);
int main (void)
{
int myarray [] = {1, 2, 3, 4, 5};
shiftright( myarray, 5);
for ( int i = 0; i < 5; i++)
{
cout << myarray[i] << ' ';
}
return (0);
}
void shiftright (int myarray[], int size, int M)
{
for (int m = (size - 1); m >= 1; m--) {
int temp = myarray[size - 1];
for (int i = (size - 1); i >= 1; i--)
{
myarray[i] = myarray[i - 1] ;
}
myarray[0] = temp;
}
}
Instead of rolling your own, simply use a standard algorithm.
if (m > 0 && size > 0)
std::rotate(myarray, myarray + m % size, myarray + size);
Looks like you're trying to perform a "rotate" operation. Have you considered creating an indexer with an offset and not actually having to rotate anything at all? (This is far less costly.)
Anyways, just remove your outer loop to shift once:
void shiftright (int myarray[], int size)
{
int temp = myarray[size - 1];
for (int i = (size - 1); i >= 1; i--)
{
myarray[i] = myarray[i - 1];
}
myarray[0] = temp;
}
Now, you may create another method to shift m times:
void shiftright (int myarray[], int size, int m)
{
for (int i = 0; i < m; i++)
{
shiftright(myarray, size);
}
}
This is obviously very costly in terms of performance, so you may want to explain what you need this for.
So I have two vectors:
vector<int> v1(size);
vector<int> v2(size);
and what I want is to calculate A[0]*B[0] - A[1]*B[1] - A[2]*B[2] - ... - A[n-1]*B[n-1]. I've tried the following
#include <iostream>
#include <vector>
using namespace std;
int main()
{
size_t size = 4;
vector<int> product; int i;
vector<int> v1(size);
vector<int> v2(size);
v1[0] = 2; v2[0] = 4;
v1[1] = 5; v2[1] = 1;
v1[2] = 9; v2[2] = 6;
v1[3] = 3; v2[3] = 7;
for(i=1;i < v1.size();++i){
product.push_back(v1[i]*v2[i]);
}
for(vector<int>::const_iterator i = product.begin(); i != product.end(); ++i)
std::cout << *i << ' ';
return 0;
}
However, this would return 5 54 21 as of v1[1]*v2[1], v1[2]*v2[2] and v1[3]*v2[3] and I want to subtract them from each other: 5-54-21.
Firstly, in your formula, the first product must be added (IOW is positive), while the remaining are subtracted. So you must treat the two cases differently.
Secondly, you can perform the calculation easily by computing an ongoing result, starting from zero:
int result = 0;
if (size >= 1) {
result += v1[0]*v2[0];
for (int i = 1; i < size; ++i)
result -= v1[i]*v2[i];
}
std::cout << result << std::endl;
What about
vector<int> v1{2,5,9,3};
vector<int> v2{4,1,6,7};
int result = std::inner_product(++v1.beginn(),v1.end(),++v2.begin(),v1[0]*v2[0],std::minus<>,std::multiplies<>);
(with C++14)
int result = std::inner_product(++v1.beginn(),v1.end(),++v2.begin(),v1[0]*v2[0],std::minus<int>,std::multiplies<int>);
(with C++98)
What I need this program to do is roll 36000 2d6, output the results of each value and how often it occurs in a table format. Unfortunately I'm unfamiliar with how arrays work. This is what I have so far:
int DiceArray()
{
int rollOne = 0;
int rollTwo = 0;
int countrolls = 0;
int sum = 0;
for (countrolls=1; countrolls<=36000; countrolls++)
{
rollOne = (rand() % 6) + 1;
rollTwo = (rand() % 6) + 1;
sum = rollOne+rollTwo;
}
}
So, I need an array for the dice results which I'm guessing is gonna look like result[11] because it lists 2 through 12 for the sum of the dice. Then I'm gonna have to make the array multidimensional; I'll need a second column for the results.
So, for instance, the result of two would occur we'll say 700 times. So I'd need something like outcome[2]. Is that right? And how would I get the right values for my array, anyways?
I suppose for the result array I just list them like so since they'll always be the same: {2, 3, 4,... 12}
But how do I output my sum to array?
Not sure, what you're asking, but it seems like you need a simple histogram. Like this:
void DiceArray()
{
int rollOne = 0;
int rollTwo = 0;
int sum = 0;
// This array holds histogram. hist[0] and hist[1] are always zero.
int hist[13] = { 0 };
for (int countrolls = 0; countrolls < 36000; ++countrolls)
{
rollOne = (rand() % 6) + 1;
rollTwo = (rand() % 6) + 1;
sum = rollOne+rollTwo;
hist[sum]++;
}
for (int i = 2; i <= 12; ++i)
{
std::cout << i << ": " << hist[i] << std::endl;
}
}
This function prints the following:
2: 949
3: 1974
4: 2898
5: 3987
6: 5133
7: 6088
8: 4944
9: 3976
10: 3075
11: 1991
12: 985
Something like this should work:
#include <iostream>
#include <random>
#include <array>
std::array<std::size_t, 13> DiceArray(const std::size_t count)
{
std::random_device device;
std::mt19937 engine(device());
std::uniform_int_distribution<std::size_t> distribution(1, 6);
std::array<std::size_t, 13> result = {};
for (std::size_t i = 0; i < count; ++i) {
++result[distribution(engine)+distribution(engine)];
}
return result;
}
int main(int argc, char* argv[])
{
auto result = DiceArray(36000);
for (std::size_t i = 0; i < result.size(); ++i) {
std::cout<<i<<" "<<result[i]<<std::endl;
}
return 0;
}
Your idea of result[11]; would work. You would have to zero-initialize it too.
int result[11] = {0};
Keep in mind that arrays are zero-based. So this array would cover the range of 0-10. You can work with that by subtracting off the minimum dice roll. Increment the corresponding array location for each roll in your loop:
++result[sum-2];
Accessing the value again requires subtracting the minimum dice roll:
int numTwos = result[2-2];
int numTens = result[10-2];
This is a C++11 answer. Based off this stack overflow answer
typedef std::mt19937 MyRNG; // the Mersenne Twister with a popular choice of parameters
std::vector< unsigned > DiceArray(
unsigned how_many_rolls, unsigned dice_count,
MyRNG& rng
)
{
// d6!
std::uniform_int_distribution<uint32_t> d6(1,6);
std::vector< unsigned > retval;
retval.resize( dice_count * 6+1 );
for (unsigned count = 0; count < how_many_rolls; ++count)
{
unsigned sum = 0;
for(unsigned i = 0; i < dice_count; ++i) {
sum += d6(rng);
}
retval[sum] += 1;
}
return retval;
}
And next we use it:
int main(int argc, char* argv[])
{
MyRNG rng;
uint32_t seed_val = 0; // populate somehow -- as `0` it will replicate the same sequence each time. A common trick is to grab the current time or some other source of entropy
rng.seed(seed_val); // avoid calling this more than once per experiment. It resets the RNG, if you call it again it will repeat the same sequence of numbers as the first time.
std::vector<unsigned> result = DiceArray(36000, 2, rng);
for (unsigned i = 0; i < result.size(); ++i) {
std::cout << i <<": " << result[i] << "\n";
}
}
I'm trying to devise an algorithm in the form of a function that accepts two parameters, an array and the size of the array. I want it to return the mode of the array and if there are multiple modes, return their average. My strategy was to take the array and first sort it. Then count all the occurrences of a number. while that number is occurring, add one to counter and store that count in an array m. So m is holding all the counts and another array q is holding the last value we were comparing.
For example: is my list is {1, 1, 1, 1, 2, 2, 2}
then i would have m[0] = 4 q[0] = 1
and then m[1] = 3 and q[1] = 2.
so the mode is q[0] = 1;
unfortunately i have had no success thus far. hoping someone could help.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, k = 0, counter = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
for(int j = 0; j < n; j++){
while(y[i] == y[j]) {
counter++;
i++;
}
}
m[k] = counter;
q[k] = y[i];
i--; //i should be 1 less since it is referring to an array subscript
k++;
counter = 0;
}
}
Even though you have some good answers already, I decided to post another. I'm not sure it really adds a lot that's new, but I'm not at all sure it doesn't either. If nothing else, I'm pretty sure it uses more standard headers than any of the other answers. :-)
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <map>
#include <iostream>
#include <utility>
#include <functional>
#include <numeric>
int main() {
std::vector<int> inputs{ 1, 1, 1, 1, 2, 2, 2 };
std::unordered_map<int, size_t> counts;
for (int i : inputs)
++counts[i];
std::multimap<size_t, int, std::greater<size_t> > inv;
for (auto p : counts)
inv.insert(std::make_pair(p.second, p.first));
auto e = inv.upper_bound(inv.begin()->first);
double sum = std::accumulate(inv.begin(),
e,
0.0,
[](double a, std::pair<size_t, int> const &b) {return a + b.second; });
std::cout << sum / std::distance(inv.begin(), e);
}
Compared to #Dietmar's answer, this should be faster if you have a lot of repetition in the numbers, but his will probably be faster if the numbers are mostly unique.
Based on the comment, it seems you need to find the values which occur most often and if there are multiple values occurring the same amount of times, you need to produce the average of these. It seems, this can easily be done by std::sort() following by a traversal finding where values change and keeping a few running counts:
template <int Size>
double mode(int const (&x)[Size]) {
std::vector<int> tmp(x, x + Size);
std::sort(tmp.begin(), tmp.end());
int size(0); // size of the largest set so far
int count(0); // number of largest sets
double sum(0); // sum of largest sets
for (auto it(tmp.begin()); it != tmp.end(); ) {
auto end(std::upper_bound(it, tmp.end(), *it));
if (size == std::distance(it, end)) {
sum += *it;
++count;
}
else if (size < std::distance(it, end)) {
size = std::distance(it, end);
sum = *it;
count = 1;
}
it = end;
}
return sum / count;
}
If you simply wish to count the number of occurences then I suggest you use a std::map or std::unordered_map.
If you're mapping a counter to each distinct value then it's an easy task to count occurences using std::map as each key can only be inserted once. To list the distinct numbers in your list simply iterate over the map.
Here's an example of how you could do it:
#include <cstddef>
#include <map>
#include <algorithm>
#include <iostream>
std::map<int, int> getOccurences(const int arr[], const std::size_t len) {
std::map<int, int> m;
for (std::size_t i = 0; i != len; ++i) {
m[arr[i]]++;
}
return m;
}
int main() {
int list[7]{1, 1, 1, 1, 2, 2, 2};
auto occurences = getOccurences(list, 7);
for (auto e : occurences) {
std::cout << "Number " << e.first << " occurs ";
std::cout << e.second << " times" << std::endl;
}
auto average = std::accumulate(std::begin(list), std::end(list), 0.0) / 7;
std::cout << "Average is " << average << std::endl;
}
Output:
Number 1 occurs 4 times
Number 2 occurs 3 times
Average is 1.42857
Here's a working version of your code. m stores the values in the array and q stores their counts. At the end it runs through all the values to get the maximal count, the sum of the modes, and the number of distinct modes.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, j = 0, k = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
j = i;
while (y[j] == y[i]) {
j++;
}
m[k] = y[i];
q[k] = j - i;
k++;
i = j;
}
int max = 0;
int modes_count = 0;
int modes_sum = 0;
for (int i=0; i < k; i++) {
if (q[i] > max) {
max = q[i];
modes_count = 1;
modes_sum = m[i];
} else if (q[i] == max) {
modes_count += 1;
modes_sum += m[i];
}
}
return modes_sum / modes_count;
}