I am trying to flatten a two dimensional array into a one dimensional array. This is what I currently have. I would like the flatten out my array so that the one dimensional array looks like this
int[] oneDim = {1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10, 11, 12};
This is what I currently have. I dont really know how to go about doing this. All help and input is appreciated.
void setup() {
int[][] twoDim = { {1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12} };
int[] oneDim = new int[twoDim.length];
for (int i = 0; i < twoDim.length; i++) {
for (int j = 0; j < twoDim[i].length; j++) {
oneDim[j] += twoDim[j][i];
}
}
println(oneDim);
}
int[][] twoDim = { {1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12} };
int x = twoDim.length;
int y = twoDim[0].length;
int[] oneDim = new int[x*y];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
oneDim[i*y + j] = twoDim[i][j];
}
}
println(oneDim);
Here's a hint: the usual formula for mapping two dimensions to one is: width*y + x, where width is the number of elements in each row (4, in your case, as given by twoDim[i].length, assuming they are all the same length), 'x' is the iterator over columns (j, in your case), and y is the iterator over rows (i for you).
You will want to check that the size of your one dimensional array is sufficient to accept all the elements of twoDim. It doesn't look big enough as it is - it needs to be twoDim[i].length * twoDim.length elements long, at least.
You're currently writing the same row of data over and over again, because you're assigning to oneDim[j] in the inner loop for every iteration of the outer loop. Try assigning to oneDim (once it is of appropriate size) using the formula I suggested at the start of this answer instead.
Related
It isn't really complicated, but I just can't figure out how to do it.
I have one set with objects, let's say they are numbers. I need to check all the possibilities of N groups (we can assume there are 3 groups, 9 objects in set), where order inside group doesn't matter ({1,2,3}, {2,1,3}, {3,2,1}, etc. are the same) and order of groups doesn't matter ([{1,2,3},{4,5,6}] is the same as [{5,4,6},{2,1,3}]).
I'm writing code in C#, but there really isn't anything I could show. The closest idea I had contained a lot of fors and ifs 😞
The solution I've used places the elements in order; this avoids any problems of duplication. It uses recursion and backtracking to find all solutions.
The critical restriction to keep from duplicating a solution is that you may not place an element into the nth partition unless all lower-numbered partitions are non-empty.
Consider your problem, 9 students in 3 partitions. We start with three empty sets
{} {} {}
We now need to place students [1, 2, 3, 4, 5, 6, 7, 8, 9] into this partition set. Call our function
place({ {}, {}, {} }, [1, 2, 3, 4, 5, 6, 7, 8, 9])
We place the students in order. Student 1 has only one place to go: the first partition. Otherwise, we would violate the restriction.
place({ {1}, {}, {} }, [2, 3, 4, 5, 6, 7, 8, 9])
Student 2 can go into either of the first two partitions (i.e. you'll need an iteration loop to cover the legal possibilities). From here, you'll cycle through two recursive calls:
place({ {1, 2}, {}, {} }, [3, 4, 5, 6, 7, 8, 9])
place({ {1}, {2}, {} }, [3, 4, 5, 6, 7, 8, 9])
In the first call, 3 cannot yet go into the 3rd partition; in the second call, it can go anywhere.
Do you see how this works? As the partitions fill up (I infer a limit of 3 students in each group), you'll need to check for a full group, as well. At the end, each time you place the final student, you have a valid, unique arrangement.
Coding is left as an exercise for the reader. :-)
Well I wrote this yesterday. It takes a lot of time to generate all solutions, but it works. I suppose I can make it faster if I use some tree to store elements (now every new group is compared with all existing groups).
Edit: Actualy now when I think about it, I'm not sure if there are possible duplicats. I wrote that when I had for loop through all elements. Maybe I can remove that "if" to make it faster. I'll check that when I'll have access to my laptop.
There were no dups. Now it's fast and result seems to be okay.
public class Group<T> : IComparable<Group<int>>
{
public Group(IEnumerable<T> elements)
{
Elements = elements.OrderBy(n => n).ToArray();
}
public T[] Elements { get; }
public bool Equals(Group<T> other)
{
if (object.ReferenceEquals(this, other))
return true;
//assume number of elements in groups are equal
for (int i = 0; i < Elements.Length; i++)
if (!Elements[i].Equals(other.Elements[i]))
return false;
return true;
}
public int CompareTo(Group<int> other)
{
int[] elements = Elements as int[];
for (int i = 0; i < Elements.Length; i++)
{
if (elements[i] < other.Elements[i])
return -1;
else if (elements[i] > other.Elements[i])
return 1;
}
return 0;
}
public override string ToString()
{
string result = "{";
for (int i = 0; i < Elements.Length; i++)
result += Elements[i] + (i == Elements.Length - 1 ? "" : ", ");
result += "}";
return result;
}
}
class Program
{
static void Main(string[] args)
{
int[] allElements = {1, 2, 3, 4, 5, 6, 7, 8, 9};
List<Group<int>> singleGroupCombinations = new List<Group<int>>();
for (int i = 0; i < allElements.Length; i++)
{
for (int j = i + 1; j < allElements.Length; j++)
{
for (int k = j + 1; k < allElements.Length; k++)
{
Group<int> newGroup = new Group<int>(new[]
{
allElements[i], allElements[j], allElements[k]
});
singleGroupCombinations.Add(newGroup);
}
}
}
List<Group<Group<int>>> groupsCombinations = new List<Group<Group<int>>>();
for (int i = 0; i < singleGroupCombinations.Count; i++)
{
for (int j = i+1; j < singleGroupCombinations.Count; j++)
{
for (int k = j+1; k < singleGroupCombinations.Count; k++)
{
Group<Group<int>> newGroup = new Group<Group<int>>(new[]
{
singleGroupCombinations[i], singleGroupCombinations[j], singleGroupCombinations[k]
});
groupsCombinations.Add(newGroup);
}
}
}
//all groups combinations in groupCombinations variable
}
}
Say I have the classic Two Sum Problem but with a twist
If I am given a list of integers and target
I need to print all the pairs of values that add up to the sum
Without repeating symmetrical values
Without reusing a value
I am trying to avoid the brute force approach for obvious reasons, but if I implement a hash-map with each value as the key and the element being the frequency of that value in the original array. How do I get the algorithm to only print each value pair once?
function findPairs(arr, target){
let hashMap = {};
let results = [];
for(let i = 0; i < arr.length; i++){
if(hashMap.hasOwnProperty(arr[i])){
hashMap[arr[i]]++;
}else{
hashMap[arr[i]] = 1;
}
}
for(let i = 0; i < arr.length; i++){
let diff = target - arr[i];
if(hashMap.hasOwnProperty(diff) && hashMap[diff] > 0){
results.push([arr[i], diff]);
hashMap[diff]--;
}
}
console.log(results);
}
findPairs([1, 3, -1, 11, 7], 10);
findPairs([5, 5, 5, 5, 5], 10);
findPairs([1, 3, -1, 11, 7], 10)
(3, 7)
(-1, 11)
findPairs([5, 5, 5], 10)
(5, 5)
findPairs([5, 5, 5, 5], 10)
(5, 5)
(5, 5)
findPairs([5, 5, 5, 5, 5], 10)
(5, 5)
(5, 5)
findPairs([5, 5, 5, 5, 5, 5 ], 10)
(5, 5)
(5, 5)
(5, 5)
This is the summary of the question as far as I understood:
Your array can have duplicate elements eg:- [1, 2, 3, 2, 4]
You want to print duplicate [4, 1, 2, 3, 2, 4] as (2, 4), (2, 4)
vector<pair<int, int> > findPairs(vector<int> arr, int target){
int size = arr.size();
map<int, int> hashMap;
for(int i = 0; i < size; i++){
// C++ map assigns 0 as default if the key is not present, C++ map uses Red Black Tree
if(hashMap[arr[i]] == 0)
hashMap[arr[i]] = 1;
else
hashMap[arr[i]]++;
}
/** Use to store result in (int, int) form
* Vector is a Dynamic array
*/
vector<pair<int, int> > results;
for(int i = 0; i < size; i++){
int diff = target - arr[i];
hashMap[arr[i]]--;
if(hashMap[diff] >= 1)
results.push_back(make_pair(arr[i], diff));
hashMap[diff]--;
}
return results;
}
This code is based on the examples you have provided in the question.
I have an array of sorted integers. Given an integer N i need to place N largest elements further away from each other so that they have maximum space between each other. The remaining elements should be placed between these big items. For example, array of 10 with N=3 would result in [0, 5, 8, 2, 6, 9, 3, 7, 10, 4].
public static void main(String[] args) {
int[] start = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
int[] end = new int[10];
int N = 4;
int step = Math.round(start.length / N );
int y = 0;
int count = 0;
for (int i = 0; i < step; i++) {
for (int j = i; j<start.length; j = j + step) {
//System.out.println(j + " " + i);
if (count < start.length && start[count] != 0) {
end[j] = start[count];
count++;
}
}
}
System.out.println(end.toString());
}
You have an array of K elements. You have N max numbers you need to distribute. Then:
Step := K/N (removing the remainder)
Take any number from N maximum and insert it at Step/2 position.
Take other maximum numbers and insert it after the previous inserted maximum number at Step distance.
Giving [1,2,3,4,5,6,7,8,9,10]. So K = 10, N = 3. Then Step = 3. So the first maximum is placed at 3/2 position
[1,10,2,3,4,5,6,7,8,9]
Then other 2 are put at 3 distance from each other:
[1,10,2,3,9,4,5,8,6,7]
The code:
std::vector<int> Distribute(std::vector<int> aSource, int aNumber)
{
auto step = aSource.size() / aNumber; // Note integer dividing.
for (int i = 0; i < aNumber; ++i)
{
auto place = aSource.end() - i * step - step / 2;
aSource.insert(place, aSource.front());
aSource.erase(aSource.begin());
}
return aSource;
}
int main()
{
std::vector<int> vec{10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10};
auto res = Distribute(vec, 4);
for (auto e : res)
{
std::cout << e << ", ";
}
std::cout << std::endl;
}
Output:
6, 5, 4, 7, 3, 2, 1, 0, 8, -1, -2, -3, -4, 9, -5, -6, -7, -8, 10, -9, -10,
I have a relatively big (say, 5000 rows by 8000 columns) and sparse matrix that is stored in compressed row storage (CRS). I am trying to get its compressed column storage (CCS) form.
Is there already an standard algorithm for doing this? One option could be reconstructing the entire matrix (40 million entries) from the CRS and then using an straightforward algorithm to obtain its CCS. However, the time complexity of this is terrible and I plan on using this algorithm on even bigger matrices. Any other ideas on how to do this?
Probably not as efficient as the Numerical Recipes code, but I came up with this that seems to work:
#include <stdio.h>
#include <string.h>
#define COLS 6
#define SIZE(a) (sizeof(a)/sizeof(*(a)))
int main() {
float f[] = {10,-2, 3, 9, 3, 7, 8, 7, 3, 8, 7, 5, 8, 9, 9,13, 4, 2, 1};
int c[] = { 0, 4, 0, 1, 5, 1, 2, 3, 0, 2, 3, 4, 1, 3, 4, 5, 1, 4, 5};
int r[] = { 0, 2, 5, 8, 12, 16, 19};
float nf[SIZE(f)];
int nc[COLS+1] = {0};
int nr[SIZE(f)];
int nn[COLS+1];
int rr[SIZE(f)];
for (int k = 0, i = 0; i < SIZE(r); i++)
for (int j = 0; j < r[i+1] - r[i]; j++)
rr[k++] = i;
for (int i = 0; i < SIZE(f); i++)
nc[c[i]+1]++;
for (int i = 1; i <= COLS; i++)
nc[i] += nc[i-1];
memcpy(nn, nc, sizeof(nc));
for (int i = 0; i < SIZE(f); i++) {
int x = nn[c[i]]++;
nf[x] = f[i];
nr[x] = rr[i];
}
for (int i = 0; i < SIZE(nf); i++) printf("%2.0f ", nf[i]);
putchar('\n');
for (int i = 0; i < SIZE(nr); i++) printf("%2d ", nr[i]);
putchar('\n');
for (int i = 0; i < SIZE(nc); i++) printf("%2d ", nc[i]);
putchar('\n');
return 0;
}
There seems to be something like a standard approach as one algorithm is described in Numerical Recipes. I'll cite the code here which should give you the idea, whereas for more details you should consult chapter 2.7. of the third edition.
NRsparseMat NRsparseMat::transpose() const {
Int i,j,k,index,m=nrows,n=ncols;
NRsparseMat at(n,m,nvals); //Initialized to zero.
//First find the column lengths for AT , i.e. the row lengths of A.
VecInt count(m,0); //Temporary counters for each row of A.
for (i=0;i<n;i++)
for (j=col_ptr[i];j<col_ptr[i+1];j++) {
k=row_ind[j];
count[k]++;
}
for (j=0;j<m;j++) //Now set at.col_ptr. 0th entry stays 0.
at.col_ptr[j+1]=at.col_ptr[j]+count[j];
for(j=0;j<m;j++) //Reset counters to zero.
count[j]=0;
for (i=0;i<n;i++) //Main loop.
for (j=col_ptr[i];j<col_ptr[i+1];j++) {
k=row_ind[j];
index=at.col_ptr[k]+count[k]; //Element’s position in column of AT .
at.row_ind[index]=i;
at.val[index]=val[j];
count[k]++; //Increment counter for next element in that column.
}
return at;
}
For my personal use, I usually rewrite code from Numerical Recipes by removing it's specific typedefs (such as Int, VecInt), rename, reformat, etc.
Given two arrays, how do you check if one is a cyclic permutation of the other?
For example, given a = [1, 2, 3, 1, 5], b = [3, 1, 5, 1, 2], and c = [2, 1, 3, 1, 5] we have that a and b are cyclic permutations but c is not a cyclic permutation of either.
Note: the arrays may have duplicate elements.
The standard trick here is to concatenate one of the arrays with itself, and then try to find the 2nd array in the concatenated array.
For example, 'a' concatenated with itself is:
[1, 2, 3, 1, 5, 1, 2, 3, 1, 5]
Since you do see 'b' in this array starting from the 3rd element then a and b are cyclic permutations.
If A and B are cyclic permutations of each other, A will be found in doubled list BB (as will B in AA).
The efficient way to handle large amounts of data, is to transform each of them into a 'canonical' form then compare to see of they're equal. For this problem you can choose as the canonical form of all the rotated permutations the one that 'sorts smallest'.
So the canonical form for 'a' and 'b' is [1, 2, 3, 1, 5] which are equal so they are acyclic permutations.
The canonical form for 'c' is [1, 3, 1, 5, 2] which is different.
Here is simple adhoc approach to findout cyclic permutations with O(n) time complexity.
a = [1, 2, 3, 1, 5], b = [3, 1, 5, 1, 2]
Find index of b[0] in a[], lets say index is 'x'.Then start
navigating in both the array's. a[] starts from index 'x' and b[]
starts from '0'. Such that both of them must have same values. If
not, they are not cyclic.
Here is the sample code.
public class CyclicPermutation {
static char[] arr = { 'A', 'B', 'C', 'D' };
static char[] brr = { 'C', 'D', 'K', 'B' };
boolean dec = false;
public static void main(String[] args) {
boolean avail = true;
int val = getFirstElementIndex(brr[0]);
if(val ==Integer.MIN_VALUE){
avail = false;
return;
}
for (int i = val, j = 0; j <= brr.length-1; ) {
if (i > arr.length-1) {
i = 0;
}
if (arr[i] == brr[j]) {
i++;
j++;
} else {
avail = false;
System.out.println(avail);
return;
}
}
System.out.println(avail);
}
public static int getFirstElementIndex(char c) {
for (int i = 0; i <= arr.length; i++) {
if (arr[i] == c) {
return i;
}
}
return Integer.MIN_VALUE;
}
}