C# Transcribing data to the second table and reversing them - c#

I am will be grateful for help because I am not sure how make this program.
I should code program with two tables. The first will fill it with numbers Random tab = new Random();. After that I should reverse numbers and fill them into second table.
I made first functionality but I am not sure how make start with second table?
class Program
{
static void Main(string[] args)
{
int[] tablica1 = new int[20];
Random tab = new Random();
for (int i = 0; i < 20; i++)
{
tablica1[i] = tab.Next(20);
Console.WriteLine("Tablica wylosowała nastepujace elementy:");
Console.WriteLine(tablica1[i]);
}
Console.Read();
int[] tablica2 = new int[20];
/*for (int i = 20; i > 0; i--)
{
}
*/
}
}

You didn't quite describe what exactly happens when you run the code, but I think the problem is with this part - as this should give you an IndexOutOfRangeException:
for (int j = tablica2.Length; j > 1 ; j--)
{
tablica2[j] = tablica1[20-j];
Console.WriteLine(tablica2[j]);
}
The array indices go form 0 to tablica2.Length - 1 (one less then the length, so the index tablica2.Length is outside the array).
Your loop goes in reverse from tablica2.Length two 2 for some reason.
So as soon as it starts executing, j is 20, but the highest index is 19.
Change the loop so it goes the full range, and change the loop body so that you don't access out-of-range indices, in one of two ways:
for (int j = tablica2.Length - 1; j >= 0 ; j--) // goes from 19 to 0
{
tablica2[j] = tablica1[tablica1.Length - j - 1];
}
or
for (int j = tablica2.Length; j > 0 ; j--) // goes from 20 to 1
{
tablica2[j - 1] = tablica1[tablica1.Length - j];
}

static void Main(string[] args)
{
int[] tablica1 = new int[20];
Random tab = new Random();
for (int i = 0; i < 20; i++)
{
tablica1[i] = tab.Next(20);
Console.WriteLine("Tablica wylosowała nastepujace elementy:");
Console.WriteLine(tablica1[i]);
}
Console.Read();
int[] tablica2 = new int[20];
for (int i = 20; i > 0; i--)
{
tablica2[i]=tablica1[20-i];
}
}
}

#Sinatr Thank You for this topic. It was really helpful but there is only one table.
#Filip Milovanović Yes, I have to make two two tables :) After reserving first, I should put elements from first to second. I changed this for, but in console I am still able to see only first one. :(
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Randomy1
{
class Program
{
static void Main(string[] args)
{
int[] tablica1 = new int[20];
Random tab = new Random();
for (int i = 0; i < 20; i++)
{
tablica1[i] = tab.Next(20);
Console.WriteLine(tablica1[i]);
}
int[] tablica2 = new int[20];
for (int j = tablica2.Length; j > 1 ; j--)
{
tablica2[j] = tablica1[20-j];
Console.WriteLine(tablica2[j]);
}
Console.Read();
}
}
}

I think this would work
for (int i = 0; i < 20; i++)
{
tablica2[i] = tablica1[20 - (i + 1)];
Console.WriteLine("Tablica 1st :: " + tablica1[i] + " Tablica 1 Reverse " + tablica1[20 - (i + 1)] + " Tablica 2 " + tablica2[i]);
}

Related

How can I fill array with unique random numbers with for-loop&if-statement?

I'm trying to fill one dimensional array with random BUT unique numbers (No single number should be same). As I guess I have a logical error in second for loop, but can't get it right.
P.S I'm not looking for a more "complex" solution - all I know at is this time is while,for,if.
P.P.S I know that it's a really beginner's problem and feel sorry for this kind of question.
int[] x = new int[10];
for (int i = 0; i < x.Length; i++)
{
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) break;
}
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i);
}
Here is a solution with your code.
int[] x = new int[10];
for (int i = 0; i < x.Length;)
{
bool stop = false;
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) {
stop = true;
break;
}
}
if (!stop)
i++;
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i]);
}
A simple trace of the posted code reveals some of the issues. To be specific, on the line…
if (x[i] == x[j]) break;
if the random number is “already” in the array, then simply breaking out of the j loop is going to SKIP the current i value into the x array. This means that whenever a duplicate is found, x[i] is going to be 0 (zero) the default value, then skipped.
The outer i loop is obviously looping through the x int array, this is pretty clear and looks ok. However, the second inner loop can’t really be a for loop… and here’s why… basically you need to find a random int, then loop through the existing ints to see if it already exists. Given this, in theory you could grab the same random number “many” times over before getting a unique one. Therefore, in this scenario… you really have NO idea how many times you will loop around before you find this unique number.
With that said, it may help to “break” your problem down. I am guessing a “method” that returns a “unique” int compared to the existing ints in the x array, may come in handy. Create an endless while loop, inside this loop, we would grab a random number, then loop through the “existing” ints. If the random number is not a duplicate, then we can simply return this value. This is all this method does and it may look something like below.
private static int GetNextInt(Random r, int[] x, int numberOfRandsFound) {
int currentRand;
bool itemAlreadyExist = false;
while (true) {
currentRand = r.Next(RandomNumberSize);
itemAlreadyExist = false;
for (int i = 0; i < numberOfRandsFound; i++) {
if (x[i] == currentRand) {
itemAlreadyExist = true;
break;
}
}
if (!itemAlreadyExist) {
return currentRand;
}
}
}
NOTE: Here would be a good time to describe a possible endless loop in this code…
Currently, the random numbers and the size of the array are the same, however, if the array size is “larger” than the random number spread, then the code above will NEVER exit. Example, if the current x array is set to size 11 and the random numbers is left at 10, then you will never be able to set the x[10] item since ALL possible random numbers are already used. I hope that makes sense.
Once we have the method above… the rest should be fairly straight forward.
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
int numberOfRandsFound = 0;
int[] ArrayOfInts = new int[DataSize];
int currentRand;
for (int i = 0; i < ArrayOfInts.Length; i++) {
currentRand = GetNextInt(random, ArrayOfInts, numberOfRandsFound);
ArrayOfInts[i] = currentRand;
numberOfRandsFound++;
}
for (int i = 0; i < ArrayOfInts.Length; i++) {
Console.WriteLine(ArrayOfInts[i]);
}
Console.ReadKey();
}
Lastly as other have mentioned, this is much easier with a List<int>…
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
List<int> listOfInts = new List<int>();
bool stillWorking = true;
int currentRand;
while (stillWorking) {
currentRand = random.Next(RandomNumberSize);
if (!listOfInts.Contains(currentRand)) {
listOfInts.Add(currentRand);
if (listOfInts.Count == DataSize)
stillWorking = false;
}
}
for (int i = 0; i < listOfInts.Count; i++) {
Console.WriteLine(i + " - " + listOfInts[i]);
}
Console.ReadKey();
}
Hope this helps ;-)
The typical solution is to generate the entire potential set in sequence (in this case an array with values from 0 to 9). Then shuffle the sequence.
private static Random rng = new Random();
public static void Shuffle(int[] items)
{
int n = list.Length;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
int temp = items[k];
items[k] = items[n];
items[n] = temp;
}
}
static void Main(string[] args)
{
int[] x = new int[10];
for(int i = 0; i<x.Length; i++)
{
x[i] = i;
}
Shuffle(x);
for(int i = 0; i < x.Length; i++)
{
Console.WritLine(x[i]);
}
}
//alternate version of Main()
static void Main(string[] args)
{
var x = Enumerable.Range(0,10).ToArray();
Shuffle(x);
Console.WriteLine(String.Join("\n", x));
}
You can simply do this:
private void AddUniqueNumber()
{
Random r = new Random();
List<int> uniqueList = new List<int>();
int num = 0, count = 10;
for (int i = 0; i < count; i++)
{
num = r.Next(count);
if (!uniqueList.Contains(num))
uniqueList.Add(num);
}
}
Or:
int[] x = new int[10];
Random r1 = new Random();
int num = 0;
for (int i = 0; i < x.Length; i++)
{
num = r1.Next(10);
x[num] = num;
}

C# Collections vs Arrays: Longest Increasing Subsequence Benefits

What's the performance penalty that I can expect if I'm using Lists over Arrays to solve the Longest Increasing Subsequence?
Will the dynamic nature of Lists improve average performance because we're not dealing with sizes we won't actually use?
PS: Any tips on improving performance while still maintaining some readability?
public static int Run(int[] nums)
{
var length = nums.Length;
List<List<int>> candidates = new List<List<int>>();
candidates.Add(new List<int> { nums[0] });
for (int i = 1; i < length; i++)
{
var valueFromArray = nums[i];
var potentialReplacements = candidates.Where(t => t[t.Count-1] > valueFromArray);
foreach (var collection in potentialReplacements)
{
var collectionCount = collection.Count;
if ((collection.Count > 1 && collection[collectionCount - 2] < valueFromArray) || (collectionCount == 1))
{
collection.RemoveAt(collectionCount - 1);
collection.Add(valueFromArray);
}
}
if (!candidates.Any(t => t[t.Count - 1] >= valueFromArray))
{
var newList = new List<int>();
foreach(var value in candidates[candidates.Count - 1])
{
newList.Add(value);
}
newList.Add(nums[i]);
candidates.Add(newList);
}
}
return candidates[candidates.Count - 1].Count;
}
Depending on the solution the results may vary. Arrays are faster when compared with lists of the same size. How more fast? Lets take a look at the c# solution below. This is a simple O(n^2) solution. I coded a version with arrays only and another one with lists only. I'm running it 1000 times and recording the values for both. Then I just print the average improvement of the array version over the list version. I'm getting over 50% improvement on my computer.
Notice that this solution uses arrays and lists with the same sizes always. Than means I never created an array bigger than the size the lists are gonna grow to in the lists version. Once you start creating arrays with a Max size that may not be filled the comparison stops to be fair.
C# code below:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace hashExample
{
class Program
{
static int RunArray(int[] array)
{
int[] dp = new int[array.Length];
dp[0] = 1;
for (int i = 1; i < array.Length; i++)
{
dp[i] = 1;
for (int j = 0; j < i; j++)
if (array[i] > array[j] && dp[i] < dp[j] + 1)
dp[i] = dp[j] + 1;
}
return dp.Max();
}
static int RunList(List<int> array)
{
List<int> dp = new List<int>(array.Count);
dp.Add(1);
for (int i = 1; i < array.Count; i++)
{
dp.Add(1);
for (int j = 0; j < i; j++)
if (array[i] > array[j] && dp[i] < dp[j] + 1)
dp[i] = dp[j] + 1;
}
return dp.Max();
}
static void Main(string[] args)
{
int arrayLen = 1000;
Random r = new Random();
List<double> values = new List<double>();
Stopwatch clock = new Stopwatch();
Console.WriteLine("Running...");
for (int i = 0; i < 100; i++)
{
List<int> list = new List<int>();
int[] array = new int[arrayLen];
for (int j = 0; j < arrayLen;j++)
{
int e = r.Next();
array[j] = e;
list.Add(e);
}
clock.Restart();
RunArray(array);
clock.Stop();
double timeArray = clock.ElapsedMilliseconds;
clock.Restart();
RunList(list);
clock.Stop();
double timeList = clock.ElapsedMilliseconds;
//Console.WriteLine(Math.Round(timeArray/timeList*100,2) + "%");
values.Add(timeArray / timeList);
}
Console.WriteLine("Arrays are " + Math.Round(values.Average()*100,1) + "% faster");
Console.WriteLine("Done");
}
}
}

Selection Sort Implementation

I'm not really sure what's wrong with the implementation I have. How would I fix this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SelectionSort
{
class Program
{
static void algorithm(int[] to_sort)
{
int bufor;
for (int i = 0; i < to_sort.Length; i++)
{
for (int j = i + 1; j < to_sort.Length; j++)
{
if (to_sort[i] >= to_sort[j])
{
bufor = to_sort[i];
to_sort[i] = to_sort[j];
to_sort[j] = bufor;
}
}
}
}
static void Main(string[] args)
{
int[] to_sort = new int[100];
Console.WriteLine("");
for (int i = 1; i < 100; i++)
{
Console.Write(to_sort[i] + " ");
}
Console.WriteLine("");
algorithm(to_sort);
Console.WriteLine("\n");
Console.WriteLine("Sorted list:");
for (int i = 0; i < 100; i++)
{
Console.Write(to_sort[i] + " ");
}
Console.Read();
}
}
}
This produces the following output:
Original list: 00000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
Sorted list: 000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
It looks like my array (int[] to_sort) was empty, am I right? How can I get this:
Original list: 123456789....100
Sorted list: 123456789...100
Perhaps you originate from the C++ world where initializing an array does not mean the array is "cleaned" (the data that happened to be located at the allocated memory remains untouched), but in C# if you initialize an array like:
int[] to_sort = new int[100];
It means you construct an array where every element is set to default(T) with T the type. For an int that is 0 (for objects it is null, etc.). So you just constructed an array filled with zeros.
You can however for instance fill it with random numbers like:
Random rand = new Random();
for(int i = 0; i < to_sort.Length; i++) {
to_sort[i] = rand.Next(0,1000);
}
EDIT
Based on your comment, you want to fill it with the positions, you can do this like:
for(int i = 0; i < to_sort.Length; i++) {
to_sort[i] = i+1;
}
I think the easiest and shortest way you can initialize an array of sequential numbers is like this:
int[] to_sort = Enumerable.Range(1, 100).ToArray();
What you have will just allocate the array and fill it with the default value for int, which is 0:
int[] to_sort = new int[100];

Store value from a whileloop into an array then sum the array

I'm trying to store an unknown amount of data into an array, while using a forloop to get data! My task is to find and sum all the numbers form 1 to 1000 that can be divided be 3 and 5.
for (int i = 1; i < 1001; i++)
if (i%3==0)
{
if (i%5==0)
{
//this doesn't work, have tried to convert it to string, didn't work either
int[] array = { i };
//trying to loop the values
for (int j = 0; j < array.Length; i++)
{
//how can I loop this so I dont have to write it all out?
int sum1 = array[j]
}
}
}
Console.ReadKey();
Just because computers can perform repetitive task well doesn't mean you ignore Mathematics. If I got it right, you are trying to find the sum of all the numbers less than 1000 which are divisible by both 3 and 5. So that boils down to all the multiples of 15. Now if you take the floor of 1000/15, you get the the last multiple, which in this case is 66. So, you have to sum the series:
15, 15*2, 15*3,...15*66
=15*(1+2+3+..+66) [15*sum of first 66 positive natural numbers]
=15*66*67/2
So generalizing, finding sum of all numbers less than a and divisible by b is given by:
limit = floor(a/b);
sum = b*limit*(limit+1)/2;
Something like this:
var ListOfInts=new List<int>();
for (int i = 1; i < 1001; i++) {
if (i % 3 == 0 && i % 5 == 0)
ListOfInts.Add(i);
}
var result = ListOfInts.Sum();
Perhaps this code does what you want:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<int> li = new List<int>();
for (int i = 1; i <= 1000; i++)
{
if (i%3 == 0 && i%5 == 0)
{
li.Add(i);
}
}
Console.Write("sum is " + li.Sum());
Console.ReadLine();
}
}
}
The number devides by 3 and 5 means it devides by 15. So you can start iterating from 15 and incrementing by 15 to skip some iterations:
int sum = 0;
for (int i = 15; i <= 1000; i += 15)
sum += i;
Thanks guys! Alot of good answers, i'm still trying to understand some of them but thanks :)
How come that
List<int> li = new List<int>();
for (int i = 1; i <= 1000; i++)
{
if (i%3 == 0 && i%5 == 0)
{
li.Add(i);
}
}
Console.Write("sum is " + li.Sum());
Console.ReadLine();
give me this
while the code down under
var ListofInts = new List<int>();
for (int i = 0; i < 1001; i++)
{
if (i%3==0 && i%5==0)
{
ListofInts.Add(i);
var result = ListofInts.Sum();
Console.Write(result + ", ");
}
}
gives me this?

Selection sort just working once in C# gui

I am using selection sort in GUI and the thing is that when I select selection sort and do sorting on generate numbers it sorts generated numbers for one time but if next time I will use other number it will do just the first step of sorting by just replacing two numbers and won't work then... So why it's not working again and why showing such different behavior?
The code is:-
void SelectionSort() {
int i = 0;
int j, min, temp;
min = i;
for (j = i + 1; j < 10; j++) {
if (generate[min] > generate[j]) {
min = j;
}
}
if (min != i) {
temp = generate[i];
generate[i] = generate[min];
generate[min] = temp;
//show1(generate);
}
show1(generate);
i++;
}
My guess, you need to add i=0; at the beginning.
I guess from your function that i is a global variable.
You need to reset i to 0 every time you enter the function (Inside the function)
using System;
namespace SelectionSortExample
{
class Program
{
static void Main(string[] args)
{
int[] num = { 105, 120, 10, 200, 20 };
for (int i = 0; i < num.Length; i++)
{
int minIndex = i;
for (int j = i + 1; j < num.Length; j++)
{
if (num[minIndex] > num[j])
{
minIndex = j;
}
}
int tmp = num[i];
num[i] = num[minIndex];
num[minIndex] = tmp;
}
}
}
}

Categories