get a random number when merging 2 array - c

I want to merge 2 arrays into 1. For example:
A1= 1,1
A2= 2,2
then A3 = 1,2,1,2
For example:
A1= 1
A2= 2,2,2,2
then A3 = 1,2,2,2,2
For example:
A1= 1,1,1,1
A2= 2,2
then A3 = 1,2,1,2,1,1
In last example, when I ran my code, I got 1,2,1,2,1,20.
In the second last, I got 1,2,32767,2,2.
So I guess I have a wrong code. Right after the I finished taking the element of the shorter array and fill up all the rest of the A3 with whoever is longer. But I couldn't figure out why — can you help me?
code:
int *p3=arr3; //arr3 is A3 for example, arr1 = A1..etc, all sizes are defined
int index;
int index1=0;
int index2=0;
for(index = 0; index< sizeofArr3 ; index++)
{
if(index%2==0)
{
if(index1<=sizeofArr1)
*(p3++) = arr1[index1++];
else
*(p3++) = arr2[index2++];
}
else
{
if(index2<=sizeofArr2)
*(p3++) = arr2[index2++];
else
*(p3++) = arr1[index1++];
}
}

It's this line:
if (index1 <= sizeofArr1)
and the equivalent one for index2 and sizeofArr2. You should be using < rather than <=.
The reason has to do with C's zero-based arrays. For an array of size N, the element indexes are 0 through N-1 inclusive. Because you're allowing it to access element N (the N+1th element), you're actually invoking undefined behaviour.
Theoretically, the implementation can do anything in that case, up to and including destruction of the universe. I guess you're lucky that it just decided to give you results that were slightly awry :-)

Should <= sizeOfArr1 and 2 actually be < sizeOfArr1 and 2? How are you calculating your sizes?

The tests in the loops should be:
if (index1 < sizeofArr1)
with < rather than <=, assuming that the sizeofArr1 is a count of the number of elements in the array, rather than the maximum valid index in the array. When the arrays are the same length, this discrepancy doesn't matter (so the first sequence was OK), but when the arrays are different lengths, it does matter.

Related

Why is the Index NOT out of bounds although it intuitively should?

I'm relatively new to C programming and I stumbled upon a for me unexplainable behaviour while running the following code and debugging it using gdb and lldb.
In short: When swapping the indices i and j (max i != max j) when accessing a value in a two-dimensional Array inside a double nested for-loop it does not seem to matter if I access the value using array[i][j] or array[j][i].
The two loops and arrays are mostly identical.
unsigned matrix[3][1] =
{
{3},
{4},
{5}
};
//Loop1
for (size_t i = 0; i < sizeof(matrix) / sizeof(*matrix); i++)
{
for (size_t j = 0; j < sizeof(matrix[i]) / sizeof(*matrix[i]); j++)
{
matrix[i][j] <<= 1;
printf("matrix[%zu][%zu] has the value: %d\n", i, j, matrix[i][j]);
}
}
//same two dimensional array as matrix
unsigned matrix2[3][1] =
{
{3},
{4},
{5}
};
//Loop2, basically the same loop as Loop1
for (size_t i = 0; i < sizeof(matrix2) / sizeof(*matrix2); i++)
{
for (size_t j = 0; j < sizeof(matrix2[i]) / sizeof(*matrix2[i]); j++)
{
//swapped i and j here
matrix2[j][i] <<= 1;
printf("matrix2[%zu][%zu] has the value: %d\n", j, i, matrix2[j][i]);
}
}
Am I missing here something?
In both cases i is passed the value 2 at the end of the outer loop and j the value 0 at the end of the inner loop.
Intuitively, matrix[0][2] should throw an exception as each row only has one element.
I will take a slightly different approach than the other respondents.
You are technically not reading outside of the array's boundary as far as the memory layout is concerned. Looking at it from a human perspective you are (the index [0][2] doesn't exist!), but the memory layout of the array is contiguous. Each of the "rows" of the matrix are stored next to each other.
In memory, your array is stored as: | ? | 3 | 4 | 5 | ? |
So when you index to matrix[1][0] or matrix [0][1] you are accessing the same position in memory. This would not be the case if your array was larger than 1 dimension wide.
For example, replace your array with the following one and experiment. You can access integer '4' either by indexing matrix[0][2], or matrix [1][0]. The position [0][2] shouldn't exist, but it does because the memory is contiguous.
unsigned matrix[3][2] =
{
{3, 6},
{4, 8},
{5, 10}
};
Oops, matrix[0][2] should throw an exception as each row only has one element...
Some languages do warn the programmer by an exception if they try an out of bound access, but C does not. It just invokes Undefined Behaviour. On a technical point of view, it means that the compiler does not have to test the out of bound condition. On an operational point of view, it means that anything can happen, including expected behaviour... or an immediate crash... or a modification of an unrelated variable... or...
If my C skills aren't mega-rusty you're reading "unsafe memory".
Essentially your matrix is declared as a block of bytes. After that block of bytes there are more bytes. What are they? Usually more variables that are declared as your program's data. Once you reach the end of the program's data block you reach the user code memory block (encoded ASM instructions).
Most languages perform checks and throw an exception when you run out of bounds by somehow keeping track of the last index that is valid to access. C does not do that and doing such thing is your very own responsibility. If you aren't careful you might be overwriting important parts of your program's code.
There are attacks that one can perform on C programs that don't sanitize user input, like a buffer overrun; which exploits what it's been described.
Essentially if you declare a char[] of length N and store a string that comes from outside and this string happens to be of length N+X you'll be overwriting program memory (instructions).
With the right sequence of characters you can inject your very own assembly code into a running program which doesn't sanitize user input
As your array is int and all elements are of the same size, i don't see any problem as your array is stored in contiguous space in RAM and you use a special case of matrix where inverting indexes has no side effect.
In the first loop your indexes are [0][0], [1][0], [2][0]
In the second loop your indexes are [0][0], [0][1], [0][2]
now try to linear the access, as your array is saved as linear array into the RAM.
address of element = row * NCOL + col
row: is row number
NCOL: number of columns into your matrix
col : the column number
so the linear index for :
[0][2] ==> 0 * 1 + 2 = 2 /* the third element*/
[2][0] ==> 2 * 1 + 0 = 2 /* always the third element */
But if you use a matrix of n x m , n >= 1 and m > 1 and n != m.
if you inverse the indexes, the result will not be the same.
so if you take a 4 x 2 matrix
linear index of [3][1] = 3 * 2 + 1 = 7
linear index of [1][3] = 1 * 2 + 3 = 5 /* even [1][3] is out of the range of your matrix index */
[1][3] you will manipulate the element [2][1]
So be worry when manipulating matrix indexes.

Making a character array rotate its cells left/right n times

I'm totally new here but I heard a lot about this site and now that I've been accepted for a 7 months software development 'bootcamp' I'm sharpening my C knowledge for an upcoming test.
I've been assigned a question on a test that I've passed already, but I did not finish that question and it bothers me quite a lot.
The question was a task to write a program in C that moves a character (char) array's cells by 1 to the left (it doesn't quite matter in which direction for me, but the question specified left). And I also took upon myself NOT to use a temporary array/stack or any other structure to hold the entire array data during execution.
So a 'string' or array of chars containing '0' '1' '2' 'A' 'B' 'C' will become
'1' '2' 'A' 'B' 'C' '0' after using the function once.
Writing this was no problem, I believe I ended up with something similar to:
void ArrayCharMoveLeft(char arr[], int arrsize, int times) {
int i;
for (i = 0; i <= arrsize ; i++) {
ArraySwap2CellsChar(arr, i, i+1);
}
}
As you can see the function is somewhat modular since it allows to input how many times the cells need to move or shift to the left. I did not implement it, but that was the idea.
As far as I know there are 3 ways to make this:
Loop ArrayCharMoveLeft times times. This feels instinctively inefficient.
Use recursion in ArrayCharMoveLeft. This should resemble the first solution, but I'm not 100% sure on how to implement this.
This is the way I'm trying to figure out: No loop within loop, no recursion, no temporary array, the program will know how to move the cells x times to the left/right without any issues.
The problem is that after swapping say N times of cells in the array, the remaining array size - times are sometimes not organized. For example:
Using ArrayCharMoveLeft with 3 as times with our given array mentioned above will yield
ABC021 instead of the expected value of ABC012.
I've run the following function for this:
int i;
char* lastcell;
if (!(times % arrsize))
{
printf("Nothing to move!\n");
return;
}
times = times % arrsize;
// Input checking. in case user inputs multiples of the array size, auto reduce to array size reminder
for (i = 0; i < arrsize-times; i++) {
printf("I = %d ", i);
PrintArray(arr, arrsize);
ArraySwap2CellsChar(arr, i, i+times);
}
As you can see the for runs from 0 to array size - times. If this function is used, say with an array containing 14 chars. Then using times = 5 will make the for run from 0 to 9, so cells 10 - 14 are NOT in order (but the rest are).
The worst thing about this is that the remaining cells always maintain the sequence, but at different position. Meaning instead of 0123 they could be 3012 or 2301... etc.
I've run different arrays on different times values and didn't find a particular pattern such as "if remaining cells = 3 then use ArrayCharMoveLeft on remaining cells with times = 1).
It always seem to be 1 out of 2 options: the remaining cells are in order, or shifted with different values. It seems to be something similar to this:
times shift+direction to allign
1 0
2 0
3 0
4 1R
5 3R
6 5R
7 3R
8 1R
the numbers change with different times and arrays. Anyone got an idea for this?
even if you use recursion or loops within loops, I'd like to hear a possible solution. Only firm rule for this is not to use a temporary array.
Thanks in advance!
If irrespective of efficiency or simplicity for the purpose of studying you want to use only exchanges of two array elements with ArraySwap2CellsChar, you can keep your loop with some adjustment. As you noted, the given for (i = 0; i < arrsize-times; i++) loop leaves the last times elements out of place. In order to correctly place all elements, the loop condition has to be i < arrsize-1 (one less suffices because if every element but the last is correct, the last one must be right, too). Of course when i runs nearly up to arrsize, i+times can't be kept as the other swap index; instead, the correct index j of the element which is to be put at index i has to be computed. This computation turns out somewhat tricky, due to the element having been swapped already from its original place. Here's a modified variant of your loop:
for (i = 0; i < arrsize-1; i++)
{
printf("i = %d ", i);
int j = i+times;
while (arrsize <= j) j %= arrsize, j += (i-j+times-1)/times*times;
printf("j = %d ", j);
PrintArray(arr, arrsize);
ArraySwap2CellsChar(arr, i, j);
}
Use standard library functions memcpy, memmove, etc as they are very optimized for your platform.
Use the correct type for sizes - size_t not int
char *ArrayCharMoveLeft(char *arr, const size_t arrsize, size_t ntimes)
{
ntimes %= arrsize;
if(ntimes)
{
char temp[ntimes];
memcpy(temp, arr, ntimes);
memmove(arr, arr + ntimes, arrsize - ntimes);
memcpy(arr + arrsize - ntimes, temp, ntimes);
}
return arr;
}
But you want it without the temporary array (more memory efficient, very bad performance-wise):
char *ArrayCharMoveLeft(char *arr, size_t arrsize, size_t ntimes)
{
ntimes %= arrsize;
while(ntimes--)
{
char temp = arr[0];
memmove(arr, arr + 1, arrsize - 1);
arr[arrsize -1] = temp;
}
return arr;
}
https://godbolt.org/z/od68dKTWq
https://godbolt.org/z/noah9zdYY
Disclaimer: I'm not sure if it's common to share a full working code here or not, since this is literally my first question asked here, so I'll refrain from doing so assuming the idea is answering specific questions, and not providing an example solution for grabs (which might defeat the purpose of studying and exploring C). This argument is backed by the fact that this specific task is derived from a programing test used by a programing course and it's purpose is to filter out applicants who aren't fit for intense 7 months training in software development. If you still wish to see my code, message me privately.
So, with a great amount of help from #Armali I'm happy to announce the question is answered! Together we came up with a function that takes an array of characters in C (string), and without using any previously written libraries (such as strings.h), or even a temporary array, it rotates all the cells in the array N times to the left.
Example: using ArrayCharMoveLeft() on the following array with N = 5:
Original array: 0123456789ABCDEF
Updated array: 56789ABCDEF01234
As you can see the first cell (0) is now the sixth cell (5), the 2nd cell is the 7th cell and so on. So each cell was moved to the left 5 times. The first 5 cells 'overflow' to the end of the array and now appear as the Last 5 cells, while maintaining their order.
The function works with various array lengths and N values.
This is not any sort of achievement, but rather an attempt to execute the task with as little variables as possible (only 4 ints, besides the char array, also counting the sub function used to swap the cells).
It was achieved using a nested loop so by no means its efficient runtime-wise, just memory wise, while still being self-coded functions, with no external libraries used (except stdio.h).
Refer to Armali's posted solution, it should get you the answer for this question.

Replace numbers on even positions in sorted array

I have an array sorted in ascended order. I want to replace the biggest m numbers found even positions in the array with 0.
My algorithm that I thought looks like this:
k=1;
for j=n:1 %%starting from last position to first
if(rem(j,2)==0 && (k<=m)) %%checking if the position is even & not getting over m numbers
B(j) = 0;
k = k + 1;
end
end
Can anyone point out why it is not working? Thank you!
A bit more complex
even = (n-rem(n,2)) : -2 : 1; % even indices in descending order
B( even(1:m) ) = 0; % set to zero
Note how n-rem(n,2) ensures that we start from the last even index into B.
PS,
It is best not to use j as a variable name in Matlab.
I believe this should do the trick. This works for vectors with both odd and even number of elements.
n = numel(B);
B((n-mod(n,2)):-2:(n-mod(n,2)-2*M)) = 0
or
n = mod(numel(B),2);
B((end-n:-2:end-n-2*M)) = 0
I prefer Shai's solution, but if your vector is huge, and M is relatively small, I would go with this approach, as it avoids creating a vector of length numel(B)/2

Suggest an Efficient Algorithm

Given an Array arr of size 100000, each element 0 <= arr[i] < 100. (not sorted, contains duplicates)
Find out how many triplets (i,j,k) are present such that arr[i] ^ arr[j] ^ arr[k] == 0
Note : ^ is the Xor operator. also 0 <= i <= j <= k <= 100000
I have a feeling i have to calculate the frequencies and do some calculation using the frequency, but i just can't seem to get started.
Any algorithm better than the obvious O(n^3) is welcome. :)
It's not homework. :)
I think the key is you don't need to identify the i,j,k, just count how many.
Initialise an array size 100
Loop though arr, counting how many of each value there are - O(n)
Loop through non-zero elements of the the small array, working out what triples meet the condition - assume the counts of the three numbers involved are A, B, C - the number of combinations in the original arr is (A+B+C)/!A!B!C! - 100**3 operations, but that's still O(1) assuming the 100 is a fixed value.
So, O(n).
Possible O(n^2) solution, if it works: Maintain variable count and two arrays, single[100] and pair[100]. Iterate the arr, and for each element of value n:
update count: count += pair[n]
update pair: iterate array single and for each element of index x and value s != 0 do pair[s^n] += single[x]
update single: single[n]++
In the end count holds the result.
Possible O(100 * n) = O(n) solution.
it solve problem i <= j <= k.
As you know A ^ B = 0 <=> A = B, so
long long calcTripletsCount( const vector<int>& sourceArray )
{
long long res = 0;
vector<int> count(128);
vector<int> countPairs(128);
for(int i = 0; i < sourceArray.size(); i++)
{
count[sourceArray[i]]++; // count[t] contain count of element t in (sourceArray[0]..sourceArray[i])
for(int j = 0; j < count.size(); j++)
countPairs[j ^ sourceArray[i]] += count[j]; // countPairs[t] contain count of pairs p1, p2 (p1 <= p2 for keeping order) where t = sourceArray[i] ^ sourceArray[j]
res += countPairs[sourceArray[i]]; // a ^ b ^ c = 0 if a ^ b = c, we add count of pairs (p1, p2) where sourceArray[p1] ^ sourceArray[p2] = sourceArray[i]. it easy to see that we keep order(p1 <= p2 <= i)
}
return res;
}
Sorry for my bad English...
I have a (simple) O(n^2 log n) solution which takes into account the fact that i, j and k refer to indices, not integers.
A simple first pass allow us to build an array A of 100 values: values -> list of indices, we keep the list sorted for later use. O(n log n)
For each pair i,j such that i <= j, we compute X = arr[i]^arr[j]. We then perform a binary search in A[X] to locate the number of indices k such that k >= j. O(n^2 log n)
I could not find any way to leverage sorting / counting algorithm because they annihilate the index requirement.
Sort the array, keeping a map of new indices to originals. O(nlgn)
Loop over i,j:i<j. O(n^2)
Calculate x = arr[i] ^ arr[j]
Since x ^ arr[k] == 0, arr[k] = x, so binary search k>j for x. O(lgn)
For all found k, print mapped i,j,k
O(n^2 lgn)
Start with a frequency count of the number of occurrences of each number between 1 and 100, as Paul suggests. This produces an array freq[] of length 100.
Next, instead of looping over triples A,B,C from that array and testing the condition A^B^C=0,
loop over pairs A,B with A < B. For each A,B, calculate C=A^B (so that now A^B^C=0), and verify that A < B < C < 100. (Any triple will occur in some order, so this doesn't miss triples. But see below). The running total will look like:
Sum+=freq[A]*freq[B]*freq[C]
The work is O(n) for the frequency count, plus about 5000 for the loop over A < B.
Since every triple of three different numbers A,B,C must occur in some order, this finds each such triple exactly once. Next you'll have to look for triples in which two numbers are equal. But if two numbers are equal and the xor of three of them is 0, the third number must be zero. So this amounts to a secondary linear search for B over the frequency count array, counting occurrences of (A=0, B=C < 100). (Be very careful with this case, and especially careful with the case B=0. The count is not just freq[B] ** 2 or freq[0] ** 3. There is a little combinatorics problem hiding there.)
Hope this helps!

Puzzle : finding out repeated element in an Array

Size of an array is n.All elements in the array are distinct in the range of [0 , n-1] except two elements.Find out repeated element without using extra temporary array with constant time complexity.
I tried with o(n) like this.
a[]={1,0,0,2,3};
b[]={-1,-1,-1,-1,-1};
i=0;
int required;
while(i<n)
{
b[a[i]]++;
if(b[a[i]==1)
required=a[i];
}
print required;
If there is no constraint on range of numbers i.e allowing out of range also.Is it possible get o(n) solution without temporary array.
XOR all the elements together, then XOR the result with XOR([0..n-1]).
This gives you missing XOR repeat; since missing!=repeat, at least one bit is set in missing XOR repeat.
Pick one of those set bits. Iterate over all the elements again, and only XOR elements with that bit set. Then iterate from 1 to n-1 and XOR those numbers that have that bit set.
Now, the value is either the repeated value or the missing value. Scan the elements for that value. If you find it, it's the repeated element. Otherwise, it's the missing value so XOR it with missing XOR repeat.
Look what is first and last number
Calculate SUM(1) of array elements without duplicate (like you know that sum of 1...5 = 1+2+3+4+5 = 15. Call it SUM(1)). As AaronMcSmooth pointed out, the formula is Sum(1, n) = (n+1)n/2.
Calculate SUM(2) of the elements in array that is given to you.
Subtract SUM(2) - SUM(1). Whoa! The result is the duplicate number (like if a given array is 1, 2, 3, 4, 5, 3, the SUM(2) will be 18. 18 - 15 = 3. So 3 is a duplicate).
Good luck coding!
Pick two distinct random indexes. If the array values at those indexes are the same, return true.
This operates in constant time. As a bonus, you get the right answer with probability 2/n * 1/(n-1).
O(n) without the temp array.
a[]={1,0,0,2,3};
i=0;
int required;
while(i<n)
{
a[a[i] % n] += n;
if(a[a[i] % n] >= 2 * n)
required = a[i] % n;
}
print required;
(Assuming of course that n < MAX_INT - 2n)
This example could be useful for int, char, and string.
char[] ch = { 'A', 'B', 'C', 'D', 'F', 'A', 'B' };
Dictionary<char, int> result = new Dictionary<char, int>();
foreach (char c in ch)
{
if (result.Keys.Contains(c))
{
result[c] = result[c] + 1;
}
else
{
result.Add(c, 1);
}
}
foreach (KeyValuePair<char, int> pair in result)
{
if (pair.Value > 1)
{
Console.WriteLine(pair.Key);
}
}
Console.Read();
Build a lookup table. Lookup. Done.
Non-temporary array solution:
Build lookup into gate array hardware, invoke.
The best I can do is O(n log n) in time and O(1) in space:
The basic idea is to perform a binary search of the values 0 through n-1, passing over the whole array of n elements at each step.
Initially, let i=0, j=n-1 and k=(i+j)/2.
On each run through the array, sum the elements whose values are in the range i to k, and count the number of elements in this range.
If the sum is equal to (k-i)*(k-i+1)/2 + i*(k-i+1), then the range i through k has neither the duplicate nor the omitted value. If the count of elements is less than k-i+1, then the range has the omitted value but not the duplicate. In either case, replace i by k+1 and k by the new value of (i+j)/2.
Else, replace j by k and k by the new value of (i+j)/2.
If i!=j, goto 2.
The algorithm terminates with i==j and both equal to the duplicate element.
(Note: I edited this to simplify it. The old version could have found either the duplicate or the omitted element, and had to use Vlad's difference trick to find the duplicate if the initial search turned up the omitted value instead.)
Lazy solution: Put the elements to java.util.Set one by one by add(E) until getting add(E)==false.
Sorry no constant-time. HashMap:O(N), TreeSet:O(lgN * N).
Based on #sje's answer. Worst case is 2 passes through the array, no additional storage, non destructive.
O(n) without the temp array.
a[]={1,0,0,2,3};
i=0;
int required;
while (a[a[i] % n] < n)   
a[a[i++] % n] += n;
required = a[i] % n;
while (i-->0)
a[a[i]%n]-=n;
print required;
(Assuming of course that n < MAX_INT/2)

Resources