Move/remove an element in one array into another - c

I'm doing a project in C involving arrays. What I have is an array of 7 chars, I need to populate an array with 4 random elements from the 7. Then I compare an array I fill myself to it. I don't want to allow repeats. I know how to compare each individual element to another to prevent it but obviously this isn't optimal. So if I remove the elements from the array as I randomly pick them I remove any chance of them being duplicated, or so I think. My question is how would I do this?
Example:
char name[2+1] = {'a','b'};
char guess[2+1] = {};
so when it randomly picks a or b and puts it in guess[],
but the next time it runs it might pick the same. Removing it will get rid of that chance.
In bigger arrays it would make it faster then doing all the comparing.
Guys it just hit me.
Couldn't I switch the element I took with the last element in the array and shrink it by one?
Then obviously change the rand() % x modulus by 1 each time?

I can give you steps to do what you intend to do. Code it yourself. Before that let's generalize the problem.
You've an array of 'm' elements and you've to fill another 'n' length
array by choosing random elements from first array such that there are
no repetition of number. Let's assume all numbers are unique in first
array.
Steps:
Keep a pointer or count to track the current position in array.
Initialize it to zeroth index initially. Let's call it current.
Generate a valid random number within the range of current and 'm'. Let's say its i. Keep generating until you find something in range.
Fill second_array with first_array[i].
Swap first_array[i] and first_array[current] and increment current but 1.
Repeat through step 2 'n' times.
Let's say your array is 2, 3, 7, 5, 8, 12, 4. Its length is 7. You've to fill a 5 length array out of it.
Initialize current to zero.
Generate random index. Let's say 4. Check if its between current(0) and m(7). It is.
Swap first_array[4] and first_array[0]. array becomes 8, 3, 7, 5, 2, 12, 4
Increment current by 1 and repeat.

Here are two possible ways of "removing" items from an array in C (there are other possible way too):
Replace the item in the array with another items which states that this item is not valid.
For example, if you have the char array
+---+---+---+---+---+---+
| F | o | o | b | a | r |
+---+---+---+---+---+---+
and you want to "remove" the b the it could look like
+---+---+---+------+---+---+
| F | o | o | \xff | a | r |
+---+---+---+------+---+---+
Shift the remaining content of the array one step up.
To use the same example from above, the array after shifting would look like
+---+---+---+---+---+---+
| F | o | o | a | r | |
+---+---+---+---+---+---+
This can be implemented by a simple memmove call.
The important thing to remember for this is that you need to keep track of the size, and decrease it every time you remove a character.
Of course both these methods can be combined: First use number one in a loop, and once done you can permanently remove the unused entries in the array with number two.

To don't forget that an array is just a pointer on the beginning of a set of items of the same type in C. So to remove an element, you simply have to replace the element at the given index with a value that shows that it is not a valid entry i.e. null.
As the entry is a simple number, there is no memory management issue (that I know of) but if it were an object, you would have to delete it if it is the last reference you have on it.
So let's keep it simple:
array2[index2] = array1[index1];
array1[index1] = null;
The other way is to change the size of the original array so that it contains one less element, as Joachim stated in his answer.

Related

#VALUES! while using IF and OR together

I have the File as following format
Name Number Position
A 1
B 2
C 3
D 4
Now on position A3 , I applied =IF(B2=1,"Goal Keeper",OR(IF(B2=2,"Defender",OR(IF(B2=3,"MidField","Striker"))))) But it giving me an error #value!
Looked up at google, and my formula is correct.
What i basically want it
1- Goalkeeper 2-Defender 3-Midfield 4-Striker
Yes the other way is to to just filter the number and copy paste the text
But I want to do it using formula and want to know where did I go wrong.
Your immediate problem lies with the expression (for example):
OR(IF(B2=3,"MidField","Striker"))
| \__/ \________/ \_______/ |
| bool string string |
\____________________________/
string
The OR function expects a series of boolean values (true or false) and you're giving it a string value from the inner IF.
You don't actually need the or bits in this specific case, the if is a full if-else. So you can just use:
=IF(B1=1,"Goal Keeper",IF(B2=2,"Defender",IF(B2=3,"MidField","Striker")))
This means that B1=1 will result in "Goal Keeper", otherwise it will evaluate IF(B2=2,"Defender",IF(B2=3,"MidField","Striker")).
Then that means that, if B2=2, it will result in "Defender", otherwise it will evaluate IF(B2=3,"MidField","Striker").
Finally, that means the B2=3 will result in "MidField", anything else will give "Striker".
The only situation I can envisage when OR would come in handy here would be when two different numbers were to generate the same string. Let's say both 1 and 4 should give "Goalie", you could use:
=IF(OR(B1=1,B1=4),"Goalie",IF(B2=2,"Defender","MidField"))
Keep in mind that a more general solution would be better implemented with the Excel lookup functions, ones that would search a table (on the spreadsheet somewhere) which mapped the integers to strings. Then, if the mapping needed to change, you would just update the table rather than going back and changing the formula in every single row.
If you are actually tasked with solving the problem by using the IF and OR function within the same equation, this is the only way I can see how:
=IF(OR(B1=1, B1 = 2, B1 = 3, B1 = 4),IF(B1 = 1, "Goal Keeper", IF(B1 = 2,"Defender",IF(B1 = 3,"MidField","Striker")))
If B1 does not equal 1-4, the OR function will return FALSE and completely bypass all of the nested IF statements.

Algorithm(or C++): Finding Subset of indexes of 2 arrays to reach end of them by jumping

Given two arrays(a,b containing only 2 decimal values), we can either move.
i+value or i-value. Where value is the element at that index in that array.
We need to reach the last element by traversing each element only once and we start with 1st element.
Now how can we find out subset of values to exchange between a and b so that we can reach the last index.
eg a = 112 b = 212 here both can reach the end so empty set will also do. Any other set isn't there that will do. So ans will be : {} only.
Eg 2: a= 2211 b= 1111. Here both string can iterate and reach last element. Now if I replace (1,2) indexes in a and b I.e now a=1111 and b= 2211 both the strings can still reach the end . Similarly we can also replace {3},{4},{3,4} and we can still go to last index in both strings.
Now is there a algorithm to do so ?
How can we find out these subsets ?
Maybe a dp Solution ? I would be thankful if someone can guide me through the code if possible.

No. of paths in integer array

There is an integer array, for eg.
{3,1,2,7,5,6}
One can move forward through the array either each element at a time or can jump a few elements based on the value at that index. For e.g., one can go from 3 to 1 or 3 to 7, then one can go from 1 to 2 or 1 to 2(no jumping possible here), then one can go 2 to 7 or 2 to 5, then one can go 7 to 5 only coz index of 7 is 3 and adding 7 to 3 = 10 and there is no tenth element.
I have to only count the number of possible paths to reach the end of the array from start index.
I could only do it recursively and naively which runs in exponential time.
Somebody plz help.
My recommendation: use dynamic programming.
If this key word is sufficient and you want the challenge to find a possible solution on your own, dont read any further!
Here a possible DP-algorithm on the example input {3,1,2,7,5,6}. It will be your job to adjust on the general problem.
create array sol length 6 with just zeros in it. the array will hold the number of ways.
sol[5] = 1;
for (i = 4; i>=0;i--) {
sol[i] = sol[i+1];
if (i+input[i] < 6 && input[i] != 1)
sol[i] += sol[i+input[i]];
}
return sol[0];
runtime O(n)
As for the directed graph solution hinted in the comments :
Each cell in the array represents a node. Make an directed edge from each node to the node accessable. Basically you can then count more easily the number of ways by just looking at the outdegrees on the nodes (since there is no directed cycle) however it is a lot of boiler plate to actual program it.
Adjusting the recursive solution
another solution would be to pruning. This is basically equivalent to the DP-algorithm. The exponentiel time comes from the fact, that you calculate values several times. Eg function is recfunc(index). The initial call recFunc(0) calls recFunc(1) and recFunc(3) and so on. However recFunc(3) is bound to be called somewhen again, which leads to a repeated recursive calculation. To prune this you add a Map to hold all already calculated values. If you make a call recFunc(x) you lookup in the map if x was already calculated. If yes, return the stored value. If not, calculate, store and return it. This way you get a O(n) too.

Indexing an array with a string (C)

I have an array of unsigned integers, each corresponding to a string with 12 characters, that can contain 4 different characters, namely 'A','B','C','D'. Thus the array will contain 4^12 = 16777216 elements. The ordering of the elements in the array is arbitrary; I can choose which one corresponds to each string. So far, I have implemented this as simply as that:
unsigned int my_array[16777216];
char my_string[12];
int index = string_to_index(my_string);
my_array[index] = ...;
string_to_index() simply assigns 2 bits per character like this:
A --> 00, B --> 01, C --> 10, D --> 11
For example, ABCDABCDABCD corresponds to the index (000110110001101100011011)2 = (1776411)10
However, I know for a fact that each string that is used to access the array is the previous string shifted once to the left with a new last character. For example after I access with ABCDABCDABCD, the next access will use BCDABCDABCDA, or BCDABCDABCDB, BCDABCDABCDC, BCDABCDABCDD.
So my question is:
Is there a better way to implement the string_to_index function to take under consideration this last fact, so that elements that are consecutively accessed are closer in the array? I am hoping to improve my caching performance by doing so.
edit: Maybe I was not very clear: I am looking for a completely different string to index correspondence scheme, so that the indexes of ABCDABCDABCD and BCDABCDABCDA are closer.
If the following assumptions are true for your problem then the solution you implemented is best one.
The right most char of next string is randomly selected with equal probability for each valid character
Start of the sequence is not same always (it is random).
Reason:
When I first read your question I came up with the following tree: (reduced your problem to string of length three characters and only 2 possible characters A and B for simplicity) Note that left most child of root node (AAA in this case) is always same as root node (AAA) hence I am not building that branch further.
AAA
/ \
AAB
/ \
ABA ABB
/ \ / \
BAA BAB BBA BBB
In this tree each node has its next possible sequence as child nodes. To improve on cache you need to traverse this tree using breadth-first traversal and store it in the array in the same order. For the above tree we get following string index combination.
AAA 0
AAB 1
ABA 2
ABB 3
BAA 4
BAB 5
BBA 6
BBB 7
Assuming value(A) = 0 and value(B) = 1, index can be calculated as
index = 2^0 * (value(string[2])) + 2^1 * (value(string[1])) + 2^2 * (value(string[0]))
This is same solution as you are using.
I have written a python script to check this for other combinations too (like string of length 4 characters with A B C as possible characters). Script link
So unless the 2 assumptions made at the beginning are false than your solution already takes care of cache optimisation.
I think we could define "closer" first.
For example, we could define a function F which takes a method of calculating the indices of strings. Then F will check every string's index and return a certain value based on the distance of neighbor strings' indices.
Then we can compare various ways of calculating the index and find a best one.
Of course we could examine shorter strings first.

fpdf cell positioning from array

I have an array named Array with its elements: A, B ,C,D,...,Z
I wanna generated a pdf using FPDF which will shows as below:
Elements in Array: A | B | C
D | E | F
.........
X | Y | Z
The code above only shows elements in a single column. I have no idea how to make it to display as i desire. Please help.
$pdf->Cell('50','0','Elements in Array:',0,0,'L');
$pdf->Cell('50','0',' '.$Array[0],0,0,'L');
$pdf->Ln(5);
for($i=1;$i<=count($Array);$i++)
{
$pdf->Cell('50','0','',0,0,'L');
$pdf->Cell('50','0',' '.$Array[$i],0,0,'L');
$pdf->Ln(5);
}
Here's the basic approach; you can work out the details for yourself.
Instead of $i++, use $i += 3, so that each iteration deals with 3 elements of the array. Then, in each iteration, call Cell 3 times, one for each of the three columns. Draw lines, too if you want. (The subscripts you'll use for the 3 elements are $i, $i + 1, and $i + 2.)
Each row of 3 Cells should be positioned at $y. With each iteration, increment $y by whatever spacing seems to work best.
Since the total number of elements isn't necessarily divisible by 3, you'll have to test $i to avoid referencing a nonexistent element, and then break out of the loop.

Resources