How to add a row to 2D array - c#

I have an array with 89395 rows and 100 columns.
float[][] a = Enumerable.Range(0, 89395).Select(i => new float[100]).ToArray();
I wanna get the index of last row from this array and add one row(lastindex+1) to array and insert 100 floats to the new row which are random. Also save the new index (number of new row) into the userid variable.
I wrote the below code in C#.
public float random(int newitemid)
{
a.Length = a.Length+1;
int userid = a.Length;
Random randomvalues = new Random();
float randomnum;
for (int counter = 0; counter < 100; counter++)
{
randomnum = randomvalues.Next(0, 1);
a[counter] = randomnum;
}
return a;
}

You could do this:
public float random(int newitemid)
{
// Create a new array with a bigger length and give it the old arrays values
float[][] b = new float[a.Length + 1][];
for (int i = 0; i < a.Length; i++)
b[i] = a[i];
a = b;
// Add random values to the last entry
int userid = a.Length - 1;
Random randomvalues = new Random();
float randomnum;
a[userid] = new float[100];
for (int counter = 0; counter < 100; counter++)
{
randomnum = (float)randomvalues.NextDouble(); // This creates a random value between 0 and 1
a[userid][counter] = randomnum;
}
return a;
}
However, if you use this method more than once or twice, you really should consider using a list, that's alot more efficient.
So use List<float[]> a instead.
P.S. If you don't use the parameter newitemid, then it's better to remove it from the function I guess.
Edit: I updated the randomnum to actually generate random numbers instead of 0's

Related

Fill 2d array with unique random numbers from 0 to 15 C#

I can't fill it with numbers to 0 - 15 then shuffle the array, so that's not the solution
I used this code in C but now in c# it doesn't work, for some reason this code let some numbers pass the do while.
Random r = new Random();
bool unique;
int rand_num;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
do
{
unique = true;
rand_num = r.Next(16);
for (int k = 0; k < 4; k++)
{
for (int l = 0; l < 4; l++)
{
if (numbers[k, j] == rand_num)
{
unique = false;
}
}
}
} while (!unique);
numbers[i, j] = rand_num;
}
}
}
If the list of possible numbers is small, as in this case, just create the full list and randomise it first, then take the items in the order they appear. In your case, you can put the randomised numbers into a queue, then dequeue as required.
var r = new Random();
var numberQueue = new Queue<int>(Enumerable.Range(0, 16).OrderBy(n => r.NextDouble()));
var numbers = new int[4, 4];
for (var i = 0; i <= numbers.GetUpperBound(0); i++)
{
for (var j = 0; j <= numbers.GetUpperBound(1); j++)
{
numbers[i, j] = numberQueue.Dequeue();
}
}
I suggest you to use the Fisher-Yates algorithm to generate your non-repeatable sequence of random numbers.
It would be very straight-forward to implement a code to fill in a 2d array with those numbers, then.
List<int> seq = Enumerable.Range(0,16).ToList();
int[,] numbers = new int[4,4];
Random r = new();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int n = r.Next(0, seq.Count);
numbers[i,j] = seq[n];
seq.RemoveAt(n);
}
}
The approach you have taken may end up in continuous looping and take lot of time to complete.
Also checking for value in 2D using nested for loop is not efficient.
You can use HashSet to keep track of unique value. Searching in HashSet is fast.
following is the code approach I suggest.
var hashSet = new HashSet<int>();
var r = new Random();
var arr = new int[4, 4];
for(var i = 0;i<4;i++)
{
for(var j = 0;j<4;j++)
{
// Generate random value between 0 and 16.
var v = r.Next(0, 16);
// Check if the hashSet has the newly generated random value.
while(hashSet.Contains(v))
{
// generate new random value if the hashSet has the earlier generated value.
v = r.Next(0, 16);
}
//Add value to the hashSet.
hashSet.Add(v);
// add value to the 2D array.
arr[i, j] = v;
}
}
I hope this will help solving your issue.
The problem with your current approach is that as you get closer to the end of the array, you have to work harder and harder to get the next random value.
Imagine you roll a die, and each time you want to get a unique value. The first time you roll, any result will be unique. The next time, you have a 1/6 chance of getting a number that has already been obtained. And then a 2/6 chance, etc. and in the end most of your rolls will be non-unique.
In your example, you have 16 places that you want to fill with numbers 0 to 15. This is not a case of randomly generating numbers, but randomly placing them. How do we do this with a deck of cards? We shufle them!
My proposal is that you fill the array with unique sequential values and then shuffle them:
Random random = new Random();
int dim1 = array.GetLength(0);
int dim2 = array.GetLength(1);
int length = dim1 * dim2;
for (int i = 0; i < length; ++i)
{
int x = i / dim1;
int y = i % dim1;
array[x, y] = i; // set the initial values for each cell
}
// shuffle the values randomly
for (int i = 0; i < length; ++i)
{
int x1 = i / dim1;
int y1 = i % dim1;
int randPos = random.Next(i, length);
int x2 = randPos / dim1;
int y2 = randPos % dim1;
int tmp = array[x1, y1];
array[x1, y1] = array[x2, y2];
array[x2, y2] = tmp;
}
The shuffle in this code is based on the shuffle found here
int[,] numbers = new int[4, 4];
Random r = new Random();
bool unique;
int rand_num;
List<int> listRandom = new List<int> { };
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < 4; j++ )
{
do
{
unique = false;
if (!listRandom.Contains( rand_num = r.Next( 0, 16 )))
{
listRandom.Add( rand_num );
numbers[i, j] = rand_num;
unique = true;
}
} while ( !unique );
}
}

Generating random numbers without repeating.C# [duplicate]

This question already has answers here:
Random number generator with no duplicates
(12 answers)
Closed 2 years ago.
Hi everyone I am trying to generate 6 different numbers on the same line in c# but the problem that i face is some of the numbers are repeating on the same line.Here is my code to
var rand = new Random();
List<int> listNumbers = new List<int>();
int numbers = rand.Next(1,49);
for (int i= 0 ; i < 6 ;i++)
{
listNumbers.Add(numbers);
numbers = rand.Next(1,49);
}
somewhere my output is
17 23 23 31 33 48
Check each number that you generate against the previous numbers:
List<int> listNumbers = new List<int>();
int number;
for (int i = 0; i < 6; i++)
{
do {
number = rand.Next(1, 49);
} while (listNumbers.Contains(number));
listNumbers.Add(number);
}
Another approach is to create a list of possible numbers, and remove numbers that you pick from the list:
List<int> possible = Enumerable.Range(1, 48).ToList();
List<int> listNumbers = new List<int>();
for (int i = 0; i < 6; i++)
{
int index = rand.Next(0, possible.Count);
listNumbers.Add(possible[index]);
possible.RemoveAt(index);
}
listNumbers.AddRange(Enumerable.Range(1, 48)
.OrderBy(i => rand.Next())
.Take(6))
Create a HashSet and generate a unique random numbers
public List<int> GetRandomNumber(int from,int to,int numberOfElement)
{
var random = new Random();
HashSet<int> numbers = new HashSet<int>();
while (numbers.Count < numberOfElement)
{
numbers.Add(random.Next(from, to));
}
return numbers.ToList();
}
Make it a while loop and add the integers to a hashset. Stop the loop when you have six integers.
Instead of using a List, you should use an HashSet. The HashSet<> prohibites multiple identical values. And the Add method returns a bool that indicates if the element was added to the list, Please find the example code below.
public static IEnumerable<int> GetRandomNumbers(int count)
{
HashSet<int> randomNumbers = new HashSet<int>();
for (int i = 0; i < count; i++)
while (!randomNumbers.Add(random.Next()));
return randomNumbers;
}
I've switched your for loop with a do...while loop and set the stopping condition on the list count being smaller then 6.
This might not be the best solution but it's the closest to your original code.
List<int> listNumbers = new List<int>();
do
{
int numbers = rand.Next(1,49);
if(!listNumbers.Contains(number)) {
listNumbers.Add(numbers);
}
} while (listNumbers.Count < 6)
The best approach (CPU time-wise) for such tasks is creating an array of all possible numbers and taking 6 items from it while removing the item you just took from the array.
Example:
const int min = 1, max = 49;
List<int> listNumbers = new List<int>();
int[] numbers = new int[max - min + 1];
int i, len = max - min + 1, number;
for (i = min; i < max; i++) numbers[i - min] = i;
for (i = 0; i < 6; i++) {
number = rand.Next(0, len - 1);
listNumbers.Add(numbers[number]);
if (number != (len - 1)) numbers[number] = numbers[len - 1];
len--;
}
If you are not worried about the min, max, and range then you can use this.
var nexnumber = Guid.NewGuid().GetHashCode();
if (nexnumber < 0)
{
nexnumber *= -1;
}
What you do is to generate a random number each time in the loop. There is a chance of course that the next random number may be the same as the previous one. Just add one check that the current random number is not present in the sequence. You can use a while loop like: while (currentRandom not in listNumbers): generateNewRandomNumber
Paste the below in the class as a new method
public int randomNumber()
{
var random = new Random();
int randomNumber = random.Next(10000, 99999);
return randomNumber;
}
And use the below anywhere in the tests wherever required
var RandNum = randomNumber();
driver.FindElement(By.CssSelector("[class='test']")).SendKeys(**RandNum**);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int[] que = new int[6];
int x, y, z;
Random ran = new Random();
for ( x = 0; x < 6; x++)
{
que[x] = ran.Next(1,49);
for (y = x; y >= 0; y--)
{
if (x == y)
{
continue;
}
if (que[x] == que[y])
{
que[x] = ran.Next(1,49);
y = x;
}
}
}
listBox1.Items.Clear();
for (z = 0; z < 6; z++)
{
listBox1.Items.Add(que[z].ToString());
}
}
}

I have a function that makes an array and shuffles it but I don't know how to call it in the way I want to

This is a function that makes an array and fills it from LoLim till HiLim and then shuffles the order:
static Random random = new Random(); //these two statics are to make a random number, i need the first static to be outside the function so it won't keep making the same random number
static int RandomNum(int LoLim, int HiLim, int index)
{
var nums = Enumerable.Range(LoLim,HiLim).ToArray(); //these next lines make an array from LoLim to HiLim and then shuffle it
for (int i = 0; i < nums.Length; i++)
{
int randomIndex = random.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
return nums[index];
Then I have this function that makes a 2 dimensional array and then prints it. It uses RandomNum but not in the way I want to, but I don't know how to make it work.
static Array Matrix(int Rows, int Columns) //this is a function to initiate and print the array
{
int[,] LotteryArray = new int[Rows, Columns];
for (int i = 0; i < LotteryArray.GetLength(0); i++) //this is a series of loops to initiate and print the array
{
for (int j = 0; j < LotteryArray.GetLength(1); j++)
{
LotteryArray[i, j] = RandomNum(1,46,j); //the numbers are supposed to be between 1 and 45, so i tell it to do it until 46 because the upper limit is exclusive
Console.Write("{0,3},", LotteryArray[i, j]); //the {0,3} the 3 is three spaces after the first variable
}
Console.WriteLine();
}
return LotteryArray;
Basically I want it to call to RandomNum every "row" so it could shuffle the array, then I want it to pull out nums[index] and print it out. The reason I want this is so I can have non repeating random numbers in every row. For example: I don't want a row to be "21, 4, 21, 5, 40, 30".
There are various problems with your code, even if it worked. The "logical" problems are:
You are using a biased shuffling algorithm. You should use Fisher-Yates to do correct shuffling (see http://blog.codinghorror.com/the-danger-of-naivete/)
If you really want to do a "good" shuffling, you shouldn't use the Random number generator, and instead use the RNGCryptoServiceProvider (see http://www.cigital.com/papers/download/developer_gambling.php, but note that this is a much lesser problem than the other other one... we can survive with "a little less random" shuffles, if are the generated shuffles are all equiprobable)
You are using wrongly the arguments of Enumerable.Range()
Your coding problem is different: you have to save the shuffled row somewhere, and then take the first column values.
Here I'm using a class to encapsulate a row with shuffling
public class ShuffledRow
{
public static readonly Random Random = new Random();
public readonly int[] Row;
/// <summary>
/// Generates and shuffles some numbers
/// from min to max-1
/// </summary>
/// <param name="min"></param>
/// <param name="max">Max is excluded</param>
public ShuffledRow(int min, int max)
{
int count = max - min;
Row = Enumerable.Range(min, count).ToArray();
Shuffle(Row);
}
private static void Shuffle<T>(T[] array)
{
// Fisher-Yates correct shuffling
for (int i = array.Length - 1; i > 0; i--)
{
int j = Random.Next(i + 1);
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
Another problem: don't ever use multidimensional arrays in C# unless you know what you are doing. Sadly they are a bastard-and-forgotten child of .NET. Use jagged arrays (arrays of arrays).
public static int[][] Matrix(int rows, int columns)
{
int[][] lottery = new int[rows][];
for (int i = 0; i < lottery.Length; i++)
{
ShuffledRow sr = new ShuffledRow(1, 46);
lottery[i] = sr.Row;
Array.Resize(ref lottery[i], columns);
Console.WriteLine(
string.Join(",", lottery[i].Select(
x => string.Format("{0,3}", x))));
}
return lottery;
}
public static int[][] Matrix(int rows, int columns)
{
int[][] lottery = new int[rows][];
for (int i = 0; i < lottery.Length; i++)
{
ShuffledRow sr = new ShuffledRow(1, 46);
lottery[i] = new int[columns];
for (int j = 0; j < columns; j++)
{
lottery[i][j] = sr.Row[j];
Console.Write("{0,3},", lottery[i][j]);
}
Console.WriteLine();
}
return lottery;
}
I have prepared two versions of the Matrix function, one that is more similar to the one you are using, one that is more LINQ and "advanced".
to generate random numbers really do not use random function, use this:
private static RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
// Main method.
public static int[] generateTrueRandomOK()
{
const int totalRolls = 2500;
int[] results = new int[50]; //Number of random ints that you need
// Roll the dice 25000 times and display
// the results to the console.
for (int x = 0; x < totalRolls; x++)
{
byte roll = RollDice((byte)results.Length);
results[roll - 1]++;
}
return results;
}
// This method simulates a roll of the dice. The input parameter is the
// number of sides of the dice.
public static byte RollDice(byte numberSides)
{
if (numberSides <= 0)
throw new ArgumentOutOfRangeException("numberSides");
// Create a byte array to hold the random value.
byte[] randomNumber = new byte[1];
do
{
// Fill the array with a random value.
rngCsp.GetBytes(randomNumber);
}
while (!IsFairRoll(randomNumber[0], numberSides));
// Return the random number mod the number
// of sides. The possible values are zero-
// based, so we add one.
return (byte)((randomNumber[0] % numberSides) + 1);
}
private static bool IsFairRoll(byte roll, byte numSides)
{
// There are MaxValue / numSides full sets of numbers that can come up
// in a single byte. For instance, if we have a 6 sided die, there are
// 42 full sets of 1-6 that come up. The 43rd set is incomplete.
int fullSetsOfValues = Byte.MaxValue / numSides;
// If the roll is within this range of fair values, then we let it continue.
// In the 6 sided die case, a roll between 0 and 251 is allowed. (We use
// < rather than <= since the = portion allows through an extra 0 value).
// 252 through 255 would provide an extra 0, 1, 2, 3 so they are not fair
// to use.
return roll < numSides * fullSetsOfValues;
}
You could use jagged arrays:
Random random = new Random();
int[] RandomNum(int LoLim, int HiLim)
{
var nums = Enumerable.Range(LoLim,HiLim).ToArray();
for (int i = 0; i < nums.Length; i++)
{
int randomIndex = random.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
return nums;
}
int[][] Matrix(int Rows, int Columns)
{
int[][] LotteryArray = new int[Rows][];
for (int i = 0; i < LotteryArray.Length; i++)
{
LotteryArray[i] = RandomNum(1,46);
for (int j = 0; j < LotteryArray[i].Length; j++)
{
Console.Write("{0,3},", LotteryArray[i][j]);
}
Console.WriteLine();
}
return LotteryArray;
}

How to add numbers in a listBox

My program is supposed to generate 24 random numbers then add them all together and display them.
I've gotten them to do everything, except I can't get the first 24 numbers to add.
I tried moving the statement that collects the numbers but it didn't work.
Im not sure how to go forward.
int x = 0;
int number = 0;
int i = 0;
while (i < listBox1.Items.Count)
{
number += Convert.ToInt32(listBox1.Items[i++]);
}
totaltextBox.Text = Convert.ToString(number);
Random ran = new Random();
for(x = 0;x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0,100)));
}
fileNumbers.Text = listBox1.Items.Count.ToString();
Just replace for and while loop. if not, it cant take listBox1.Items.Count.
int x = 0;
int number = 0;
int i = 0;
Random ran = new Random();
for (x = 0; x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0, 100)));
}
while (i < listBox1.Items.Count)
{
number += Convert.ToInt32(listBox1.Items[i++]);
}
totaltextBox.Text = Convert.ToString(number);
fileNumbers.Text = listBox1.Items.Count.ToString();
As mentioned in the comments, you set your totaltextbox text too early. That way the listbox is empty when you try to accumulate the values.
Try this:
Random ran = new Random();
for (var x = 0; x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0, 100)));
}
var number = listBox1.Items.Cast<string>().Select(Int32.Parse).Sum();
var count = listBox1.Items.Count;
I also replaced your while loop with a LINQ-Expression. Also note, that in c# you can declare for-variables like in my example code. No need to declare them for the whole method (unless you want to use them after the for loop for whatever reason).
The other answers are correct. However I will add my solution which avoids some back and forth conversions and reduces iterations:
Random ran = new Random();
int total = 0;
for (int x = 0; x <= 23; x++)
{
int rn = ran.Next(0, 100);
total += rn;
listBox1.Items.Add(rn.ToString());
}
totaltextBox.Text = total.ToString();

C# Resorting an array in a unique way

I am wanting to create multiple arrays of ints(in C#). However they all must have a unique number in the index, which no other array has that number in that index. So let me try show you what I mean:
int[] ints_array = new int[30];
for (int i = 0; i < ints_array.Count(); i++)
ints_array[i] = i;
//create a int array with 30 elems with each value increment by 1
List<int[]> arrayList = new List<int[]>();
for(int i = 0; i < ints_array.Count(); i++)
arrayList.Add(ints_array[i]. //somehow sort the array here randomly so it will be unique
So I am trying to get the arrayList have 30 int[] arrays and each is sorted so no array has the same int in the same index as another.
Example:
arrayList[0] = {5,2,3,4,1,6,7,8,20,21... etc }
arrayList[1] = {1,0,5,2,9,10,29,15,29... etc }
arrayList[2] = {0,28,4,7,29,23,22,17... etc }
So would this possible to sort the array in this unique kind of way? If you need anymore information just ask and ill fill you in :)
Wouldn't it be easier to create the arrays iteratively using an offset pattern?
What I mean is that if you created the first array using 1-30 where 1 is at index 0, the next array could repeat this using 2-30 where 2 is at index 0 and then wrap back to 1 and start counting forward again as soon as you go past 30. It would be an easy and repeatable way to make sure no array shared the same value/index pair.
You can do it like that:
List<int[]> arrayList = new List<int[]>();
Random rnd = new Random();
for (int i = 0; i < ints_array.Length; i++)
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
var isDuplicate = arrayList.Any(x => x.SequenceEqual(ints_array));
if (isDuplicate)
{
while (arrayList.Any(x => x.SequenceEqual(ints_array)))
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
}
}
arrayList.Add(ints_array);
}
I think, this wouldn't be so efficient for bigger numbers than 30.But in this case it shouldn't be a problem, in my machine it takes 7 milliseconds.
Jesse's idea would be best unless you needed a pure random pattern. In that case I would recommend generating a random number, checking all your previous arrays, and then placing it in an array if it did not match any other arrays current index. Otherwise, generate a new random number until you find a fresh one. Put that into a loop until all your arrays are filled.
Use a matrix (2D-array). It is easier to handle than a list of arrays. Create a random number generator. Make sure to initialize it only once, otherwise random number generator may create bad random numbers, if created in too short time intervals, since the slow PC-clock might not have ticked in between. (The actual time is used as seed value).
private static Random random = new Random();
Create two helper arrays with shuffeled indexes for rows and columns:
const int N = 30;
int[] col = CreateUniqueShuffledValues(N);
int[] row = CreateUniqueShuffledValues(N);
Then create and initialize the matrix by using the shuffeled row and column indexes:
// Create matrix
int[,] matrix = new int[N, N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[row[i], col[j]] = (i + j) % N;
}
}
The code uses these two helper methods:
private static int[] CreateUniqueShuffledValues(int n)
{
// Create and initialize array with indexes.
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
// Shuffel array using one variant of Fisher–Yates shuffle
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle#The_modern_algorithm
for (int i = 0; i < n; i++) {
int j = random.Next(i, n);
Swap(array, i, j);
}
return array;
}
private static void Swap(int[] array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
int size = 10;
// generate table (no duplicates in rows, no duplicates in columns)
// 0 1 2
// 1 2 0
// 2 0 1
int[,] table = new int[size, size];
for (int y = 0; y < size; y++)
for (int x = 0; x < size; x++)
table[y, x] = (y + x) % size;
// shuffle rows
Random rnd = new Random();
for (int i = 0; i < size; i++)
{
int y1 = rnd.Next(0, size);
int y2 = rnd.Next(0, size);
for (int x = 0; x < size; x++)
{
int tmp = table[y1, x];
table[y1, x] = table[y2, x];
table[y2, x] = tmp;
}
}
// shuffle columns
for (int i = 0; i < size; i++)
{
int x1 = rnd.Next(0, size);
int x2 = rnd.Next(0, size);
for (int y = 0; y < size; y++)
{
int tmp = table[y, x1];
table[y, x1] = table[y, x2];
table[y, x2] = tmp;
}
}
// sample output
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
Console.Write("{0} ", table[y, x]);
Console.WriteLine();
}

Categories