Gather all possible combinations of 2 from a list - c#

I have a list with 10 items in it. I am trying to output to console every possible pairing of 2. But it cannot pair with itself. For example
1,2
1,3
1,4 etc...
I found this to find all possible combinations within a list. Can someone help me modify it please?
private static void GetCombination(IList list)
{
var count = Math.Pow(2, list.Count);
for (var i = 1; i <= count - 1; i++)
{
var str = Convert.ToString(i, 2).PadLeft(list.Count, '0');
for (var j = 0; j < str.Length; j++)
{
if (str[j] == '1')
{
Console.Write(list[j]);
}
}
Console.WriteLine();
}
}

So if you have a list with 1 to 10, you need 1,2 1,3 1,4...1,10 - 2,1 2,3..2,10 and so on.
You just have to use bubble and check if the first index is different from the second.
For more clarification, here is an example:
List<int> mylist = new List<int>(new int[] { 1,2,3,4,5,6,7,8,9 });
GetCombination(mylist);
private static void GetCombination(IList<int> values)
{
for (int i = 0; i < values.Count; i++)
{
for (int j = 0; j < values.Count; j++)
{
if (i != j)
{
Console.WriteLine(values[i] + " " + values[j]);
}
}
}
}

This is such a easy question.Adding to the answer of #FirstOne
you can also return the List containing all the combinations from the function:
List mylist = new List(new int[] { 1,2,3,4,5,6,7,8,9 });
GetCombination(mylist);
public static IList<Tuple<int,int>> GetCombination(IList<int> values)
{
List<Tuple<int,int>> _temp=new List<Tuple<int, int>>();
for (int i = 0; i < values.Count; i++)
{
for (int j = 0; j < values.Count; j++)
{
if (i != j)
{
_temp.Add(Tuple.Create(i, j));
}
}
}
return _temp;
}

Related

C# Sort 2D array based on key array

I'm trying to sort 2D array of chars based on 1D array as key. I need to find a char that wasn't used in key so far and then sort it based on it.
Fe:
AEITY
EDNTB
to
TEAIY
TDENB
based on key:
TEAIY
on row 0
My code struggle with an multiple chars and provide bad results:
Fe:
AAABN
TEAIY
TDENB
to
ABANA
TIEYA
TNDBE
but instead of that i get
ABANA
AIEYT
ENDBT
based on key:
ABANA
Code i figure out:
static char[][] SortSimiliarity(char[][] arr, char [] key, int arrRow)
{
Dictionary<char, int> dcKeyList = new Dictionary<char, int>();
for (var i = 0; i < key.Length; i++)
{
var counterCurrentKey = 0;
for (var j = 0; j < key.Length; j++)
{
if(key[i] == arr[arrRow][j])
{
//Console.WriteLine("{0} == {1}", key[i], arr[arrRow][j]);
if (!dcKeyList.ContainsKey(key[i]))
{
for (var k = 0; k < key.Length; k++)
{
//Console.WriteLine("x");
var temp = arr[k][j];
arr[k][j] = arr[k][i];
arr[k][i] = temp;
}
dcKeyList.Add(key[i], 1);
}
else
{
if (dcKeyList[key[i]] == counterCurrentKey)
{
Console.WriteLine("key is {0}", dcKeyList[key[i]]);
for (var k = 0; k < key.Length; k++)
{
//Console.WriteLine("x");
var temp = arr[k][j];
arr[k][j] = arr[k][i];
arr[k][i] = temp;
}
dcKeyList[key[i]]++;
}
counterCurrentKey++;
}
}
}
}
return arr;
}
I know there is something wrong with that ELSE statement, where i compare current count of char in key loop.
Thank you for your ideas.
My problem was simple. I tried to sort 2d array based on array key which i does, but i also save same result into same 2d array, without keeping tracks on changes. That can be solved with pointer logic or with new array where you copy only your sorted results without changing the base 2D array.
static char[][] SortSimiliarity(char[][] arr, char[] key, int arrRow)
{
// init dict
Dictionary<char, int> dict = new Dictionary<char, int>();
// init new matrix
char[][] tempArray = new char[5][];
for(var i = 0; i < 5; i++)
{
tempArray[i] = new char[5];
}
// copy new sorted keys
for (var i = 0; i < key.Length; i++)
{
for (var j = 0; j < key.Length; j++)
{
if (key[i] == arr[arrRow][j])
{
if (!dict.ContainsKey(key[i]))
{
dict.Add(key[i], j);
for(var k = 0; k < key.Length; k++)
{
tempArray[k][i] = arr[k][j];
}
break;
}
else
{
if(j != dict[key[i]])
{
for (var k = 0; k < key.Length; k++)
{
tempArray[k][i] = arr[k][j];
}
dict[key[i]] = j+1;
}
}
}
}
}
return tempArray;
}

C#: Build 3D-Array and fill it with data

The code I tried so far below:
private static List<List<List<int>>> threeDArrayToThreeDList(int [,,] letters) {
// 3d-array to 3d-list
List<List<List<int>>> letterslist = new List<List<List<int>>>();
List<List<int>> sublist = new List<List<int>> ();
List<int> subsublist = new List<int> ();
for (int i = 0; i < 2; i++) {
letterslist.Add (sublist);
for (int j = 0; j < 2; j++) {
letterslist[i].Add (subsublist);
for (int k = 0; k < 2; k++) {
Console.WriteLine (letterslist [i][j][k]); // Element not found
Console.WriteLine (letters [i,j,k]);
letterslist [i] [j] [k] = letters [i,j,k];
}
}
}
return letterslist;
}
Why letterslist [i][j][k] isn't found?
Your code is wrong. You need to create a list for each "index". You're code only creates 3 lists altogether.
Here's how it should work:
private static List<List<List<int>>> threeDArrayToThreeDList(int [,,] letters) {
// 3d-array to 3d-list
List<List<List<int>>> letterslist = new List<List<List<int>>>();
for (int i = 0; i < 2; i++) {
letterslist.Add (new List<List<int>> ());
for (int j = 0; j < 2; j++) {
letterslist[i].Add (new List<int> ());
for (int k = 0; k < 2; k++) {
Console.WriteLine (letters [i,j,k]);
letterslist [i] [j].Add(letters [i,j,k]);
}
}
}
return letterslist;
}
This because the letterslist [i][j] list has no elements in it.
Add an element to it, and it will get you through the line that causes the exception.
Change the code in the innermost loop as follows:
for (int k = 0; k < 2; k++) {
letterslist[i][j].Add (letters[i, j, k]);
Console.WriteLine(letterslist[i][j][k]); // Should work fine
Console.WriteLine(letters[i, j, k]);
}

What is the most efficient way to find the largest element in a matrix along with position? Also, the largest element in each column with position

I have written the following code but it looks to be far from efficient.
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
}
}
}
//Find position of largest in tempRankingData
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] == largestIntempRankingData)
{
positionLargestIntempRankingData.Add(i + "," + j);
}
}
}
//Find largest in each column
int largestInColumn = 0;
List<string> positionOfLargestInColumn = new List<string>();
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
}
}
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
}
So, I wanted to check about the most efficient way to do this.
Whilst you're finding the largest in each column, you could also be finding the largest overall. You can also capture the positions as you go:
//Find largest in each column
int largestInColumn = 0;
int largestOverall = int.MinValue;
List<string> positionOfLargestInColumn;
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
positionOfLargestInColumn.Add("0," + i);
for (int j = 1; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
positionOfLargestInColumn.Clear();
positionOfLargestInColumn.Add(j + "," + i);
}
else if(tempTankingData[j,i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
if(largestInColumn > largestOverall)
{
positionLargestIntempRankingData.Clear();
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
largestOverall = largestInColumn;
}
else if(largestInColumn == largestOverall)
{
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
}
}
1). You can find largest element and its position in one method and retrieve.
Would be caller of your method concerned about position or actual value, is a matter of concrete case.
2) You can use `yield return' technique in your matrix search (for column based search), so do not compute all column's maximas and push them into the dictionary. Dictionaries are not that fast as arrays, if you can avoid use them, do that.
3) You can keep a matrix in single dimension, long array. Have [] access operator overload, to "emulate" matrix access. Why ? If finding maximum is something frequent you might need to do during program run, having one foreach loop is faster then having 2 nested once. In case of a big matrices, single array search can be easily parallelized among different cores.
If big matrices and/or frequent calls are not your concern, just simplify your code like in points (1), (2).
For your fist two itterations you could replace with this:
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
List<KeyValuePair<double,string>> list = new List<KeyValuePair<double,string>>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
list.Add(new KeyValuePair<double, string>(largestIntempRankingData, i + "," + j)); //Add the value and the position;
}
}
}
//This gives a list of strings in which hold the position of largestInItemRankingData example "3,3"
//Only positions where the key is equal to the largestIntempRankingData;
list.Where(w => w.Key == largestIntempRankingData).ToList().Select(s => s.Value).ToList();
You can get all these pieces of information in a single scan with a little fiddling around. Something like this (converting the rows and columns to a string is trivial and better done at the end anyway):
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
int[] largestColumnRow = new int[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j] = i;
}
}
}
// largestSoFar is the biggest value in the whole matrix
// largestCol and largestRow is the column and row of the largest value in the matrix
// largestPerColumn[j] is the largest value in the jth column
// largestColumnRow[j] is the row of the largest value of the jth column
If you do need to capture all the "maxima" (for want of a better word, because that's not really what you are doing) in a column, you could just change the above code to something like this:
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
List<int>[] largestColumnRow = new List<int>[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j].Add(i);
}
}
}
// Now largestColumnRow[j] gives you a list of all the places where you found a larger
// value for the jth column

How to sort a 2D array filld with random numbers

I'm doing a class assignment,
I need to create an 2D array of random numbers and sort them either bubble or other sorting codes. I'm fine with single array, but the problem is a 2D array filled with random numbers, I just don't get it.
Random numbers should be made of (-I,I) interval it's a user input. Sorry for bad english, haven't gotten any degree. In working on visual C# windows form.
looking for simple couple cicles method.
example. : A[MxN] ->>> B[MxN] (Sorted 1.....n)
Getting the random numbers is trivial:
Random rnd;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
array[y][x] = l - rnd.Next(2 * l + 1);
Random.Next() will return a random value between 0 and the given parameter (excluding the parameter; which is the reason for the + 1).
A 2D array can be sorted just like a 1D array, it only depends how you want to handle multiple lines, e.g. is it just for display or do you want to sort every line for itself, etc.
Here's a solution which first sorts each row's columns into order, then sorts each row comparing by first column, then second, etc:
namespace StackOverflow.Demos
{
class Program
{
public static void Main(string[] args)
{
new Program();
Console.WriteLine("Done");
Console.ReadKey();
}
Program()
{
double[,] data = GenerateData();
OutputData(data, "Before");
SortData(ref data);
OutputData(data, "After");
}
double[,] GenerateData()
{
Random randomGenerator = new Random(DateTime.UtcNow.Millisecond);
double[,] data = new double[5, 5];
for (int i = 0; i < data.GetLength(0); i++)
{
for (int j = 0; j < data.GetLength(1); j++)
{
data[i, j] = (randomGenerator.NextDouble() * 2) - 1;
}
}
return data;
}
void OutputData(double[,] data, string message)
{
Console.WriteLine("=====================");
Console.WriteLine(message);
Console.WriteLine("=====================");
for (int i = 0; i < data.GetLength(0); i++)
{
for (int j = 0; j < data.GetLength(1); j++)
{
Console.Write(data[i, j]);
Console.Write("\t");
}
Console.WriteLine();
}
}
void SortData(ref double[,] data)
{
//sort sub arrays
SortDataRows(ref data);
//sort this array
for (int i = 0; i < data.GetLength(0)-1; i++)
{
for (int j = i; j < data.GetLength(0); j++)
{
for (int k = 0; k < data.GetLength(1); k++)
{
if (data[i, k].CompareTo(data[j, k]) < 0) //if already in order exit loop
{
break;
} else if (data[i, k].CompareTo(data[j, k]) > 0) //if out of order switch and loop
{
SwapRows(ref data, i, j);
break;
}//else orders are equal so far; continue to loop
}
}
}
}
void SortDataRows(ref double[,] data)
{
for (int row = 0; row < data.GetLength(0); row++)
{
for (int i = 0; i < data.GetLength(1) - 1; i++)
{
for (int j = i; j < data.GetLength(1); j++)
{
if (data[row, i].CompareTo(data[row, j]) > 0)
{
Swap<double>(ref data[row, i], ref data[row, j]);
}
}
}
}
}
void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
void SwapRows(ref double[,]data, int i, int j)
{
for (int k = 0; k < data.GetLength(1); k++)
{
Swap<double>(ref data[i, k], ref data[j, k]);
}
}
}
}
The code's not the best (haven't had a cup of tea yet), but should do what you're after.
Here's a better solution (not using a 2D array as such, but using a structure which can easily be converted to/from such an array):
sing System.Diagnostics;
namespace StackOverflow.Demos
{
class Program
{
public static void Main(string[] args)
{
new Program();
Console.WriteLine("Done");
Console.ReadKey();
}
Program()
{
List<List<double>> data = GenerateData(5, 5).ToList<List<double>>();
OutputData(data,"Before");
foreach (List<double> item in data)
{
item.Sort();
}
data.Sort(CompareListOfDoubles);
OutputData(data,"After");
}
private IEnumerable<List<double>> GenerateData(int index1, int index2)
{
Random rnd = new Random(DateTime.UtcNow.Millisecond);
List<double> result;
for (int i = 0; i < index1; i++)
{
result = new List<double>(index2);
for (int j = 0; j < index2; j++)
{
result.Add(rnd.NextDouble() * 2 - 1);
}
yield return result;
}
}
private void OutputData(List<List<double>> data, string message)
{
Console.WriteLine(message);
foreach (List<double> list in data)
{
foreach (double datum in list)
{
Console.Write(datum);
Console.Write("\t");
}
Console.WriteLine();
}
}
static int CompareListOfDoubles(List<double> a, List<double> b)
{
for (int i = 0; i < a.Count; i++)
{
if (i > b.Count) return -1;
if (a[i] > b[i]) return -1;
if (a[i] < b[i]) return 1;
}
if (b.Count > a.Count) return 1;
return 0;
}
double[,] ConvertListListDoubleTo2DArray(List<List<double>> data)
{
double[,] result = new double[data.Count, data[0].Count];
for (int i = 0; i < result.GetLength(0); i++)
{
for (int j = 0; j < result.GetLength(1); j++)
{
result[i, j] = data[i][j];
}
}
return result;
}
}

Generate all combinations up to X length from List<string> of words

How would I go about generating a list of all combinations of words up to a certain length from a List<string> source?
For example, I have a List<string> of 10,600+ words which I need to convert to a List<List<string>>, however, the sub list only needs to contain combinations up to and including a given maximum length, for this example, I'll say 3.
I don't care about the order in which the words appear in the sub list. For example, I only need 1 of the following in the list:
"laptop", "computer", "reviews"
"laptop", "reviews", "computer"
"computer", "laptop", "reviews"
"computer" "reviews", "laptop"
"reviews", "computer", "laptop"
"reviews", "laptop", "computer"
Is it even possible given the large number of combinations I would need to generate?
Any help is much appreciated.
First of all, I'm not sure that you really want to generate such huge list. If you really do, then I suggest you to consider to use iterators for lazy list generation instead of this huge list:
static void Main()
{
var words = new List<string> {"w1", "w2", "w3", "w4", "w5", "w6", "w7"};
foreach (var list in Generate(words, 3))
{
Console.WriteLine(string.Join(", ", list));
}
}
static IEnumerable<List<string>> Generate(List<string> words, int length, int ix = 0, int[] indexes = null)
{
indexes = indexes ?? Enumerable.Range(0, length).ToArray();
if (ix > 0)
yield return indexes.Take(ix).Select(x => words[x]).ToList();
if (ix > length)
yield break;
if (ix == length)
{
yield return indexes.Select(x => words[x]).ToList();
}
else
{
for (int jx = ix > 0 ? indexes[ix-1]+1 : 0; jx < words.Count; jx++)
{
indexes[ix] = jx;
foreach (var list in Generate(words, length, ix + 1, indexes))
yield return list;
}
}
}
Hopefully I didn't mess with anything.
for(int i = 0; i < list.Count; i ++)
{
list1 = new List<string> { list[i] };
listcombinations.Add(list1);
for(int j = i + 1; j < list.Count; j ++)
{
list1 = new List<string> { list[i], list[j] };
listcombinations.Add(list1);
for(int k = j + 1; k < list.Count; k ++)
{
list1 = new List<string> { list[i], list[j], list[k] };
listcombinations.Add(list1);
}
}
}
i suppose the problem is mostly to check if a combination of words exists already in the list:
what you can do for that:
//generate a dictionary with key hashcode / value list of string
Dictionary<int, List<string>> validCombinations= new Dictionary<int, List<string>>();
//generating anyway your combinations (looping through the words)
List<string> combinationToCheck = new List<string>(){"reviews", "laptop", "computer"};
//sort the words
combinationToCheck.Sort();
string combined = String.Join("", combinationToCheck.ToArray());
//calculate a hash
int hashCode = combined.GetHashCode();
//add the combination if the same hash doesnt exist yet
if(!validCombinations.ContainsKey(hashCode))
validCombinations.Add(hashCode, combinationToCheck);
private List<List<string>> GetCombinations()
{
List<List<string>> mResult= new List<List<string>>();
for (int i = 0; i < mList.Count; i++)
{
for (int k = 0; k < mList.Count; k++)
{
if (i == k) continue;
List<string> tmpList = new List<string>();
tmpList.Add(mList[i]);
int mCount = 1;
int j = k;
while (true)
{
if (j >= mList.Count) j = 0;
if (i != j)
{
tmpList.Add(mList[j]);
mCount++;
}
j += 1;
if (mCount >= mList.Count) break;
}
mResult.Add(tmpList);
}
}
return mResult;
}

Categories

Resources