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];
Related
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]);
}
As much as I tried to find a similar version in the question here, I couldn't find something.. so I am asking your help.
After reading some numbers from a textfile (now in string format), I split them in rows and columns and add them to a 2d-array (in string format as well). Now I want to convert everythinh in integers so that I can play with sorting the numbers out later.
Here is my code...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ArrayProgram
{
class Program
{
int number = 0;
int i = 0;
int k = 0;
string strnum;
public void onetohundredints()
{
StreamWriter writer = new StreamWriter("numberstored.txt");
for (i = 0; i < 10; i++)
{
for (k = 0; k < 10; k++)
{
number++;
Console.Write(number + " ");
strnum = number.ToString();
writer.Write(strnum + " ");
}
Console.WriteLine();
writer.WriteLine();
}
writer.Close();
}
public void readints()
{
StreamReader reader = new StreamReader("numberstored.txt");
string data = reader.ReadToEnd();
reader.Close();
string[,] dataarray = new string[10,10];
int[] numbers = new int[100];
string[] dataperlines = data.Split(new[] { '\r','\n' },StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<=dataperlines.Count()-1; i++)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int j=0; j<=numbersperrow.Count()-1; j++)
{
dataarray[i, j] = numbersperrow[j];
}
}
}
public static void Main(string[] args)
{
Program prog = new Program();
prog.onetohundredints();
prog.readints();
Console.ReadKey();
}
}
}
After I insert the number into the 2d-array, how do I convert all of it in integers?
If you don't have a particular reason to have an array of strings, you can just save you data as int in the first place. Just change your inner for loop to do:
var parsed = int.TryParse(numbersperrow[j], out dataarray[i, j]);
if (!parsed)
{
// Error
}
While that should work, I would suggest to re-write your ReadData method to look similar to the sample below.
public int[,] ReadData(string filePath, int xDimension, int yDimension)
{
var results = new int[xDimension, yDimension];
var lines = File.ReadLines(filePath);
for (var i = 0; i < allLines.Count(); i++)
{
var values = lines[i].Split(new[] { ' ' },
StringSplitOptions.RemoveEmptyEntries);
for (var j = 0; j < values.Count(); j++)
{
var parsed = int.TryParse(values[j], out results[i, j]);
if (!parsed) { }
}
}
return results;
}
You're putting everything into a string array. That array can only hold strings, not numbers. If you want to make the 2d array hold numbers, define it as int[,] dataarray = new int[10,10]; Next, in the final loop, simply do dataarray[i, j] = Convert.ToInt32(numbersperrow[j]);
Edit: You can use int.TryParse(numbersperrow[j], out value) if you aren't sure that numbersperrow[j] will be a number. Value will return false if the conversion is not successful.
I am happy to say that both solutions work. I now have my numbers in my 2d array. But now I wish to play with them. Let's say that I want the numbers printed on the screen in reverse order.
Having this correct solution:
int numbers;
int[,] dataarray = new int[10,10];
string[] dataperlines = data.Split(new[] { '\r','\n' },StringSplitOptions.RemoveEmptyEntries);
for(int i=0; i<=dataperlines.Count()-1; i++)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int j=0; j<=numbersperrow.Count()-1; j++)
{
numbers = int.Parse(numbersperrow[j]);
dataarray[i, j] = numbers;
Console.Write(numbers + " ");
}
Console.WriteLine();
}
I know that I have to make a double for loop. But how do I write a succesful syntax for the numbers to be printed properly?
I also tried this:
int[,] reversedarray = new int[10, 10];
reversedarray[i, j] = Array.Reverse(dataarray[i,j]);
but the dataarray[i,j] becomes red and the error "cannot convert from int to system.Array occurs... what am I missing?
I also tried this...
for (i = 10; i <= dataperlines.Count(); i--)
{
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (j =10; j <= numbersperrow.Count(); j--)
{
numbers = int.Parse(numbersperrow[j]);
reversedarray[i, j] = numbers;
Console.Write(numbers + " ");
}
Console.WriteLine();
}
But I have an IndexOutOfRange exception coming from
string[] numbersperrow = dataperlines[i].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
I understood that since I splitted the columns into rows too, it is unecessary to write it again, but I am stuck. I tried simplifying the code since I have my 2darray with its elements and I my tries were fallacious. Any more suggestions?
This is my code so far I have display all items in the array as the user enters and create an error message for duplicate numbers that deletes the duplicate and continues the loop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace midterm
{
class Program
{
static void Main(string[] args)
{
int size;
Console.WriteLine("How many numbers will you enter?");
size = Convert.ToInt32(Console.ReadLine());
int[] numbers = new int[size];
int i;
for (i = 0; i < size; i++)
{
Console.WriteLine("Enter number: ");
numbers[i] = Convert.ToInt32(Console.ReadLine());
}
for (i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (i != j)
{
if (numbers[j] == numbers[i])
{
int k = j;
while (k < size - 1)
{
numbers[k] = numbers[k + 1];
k++;
}
size--;
}
}
}
}
Console.WriteLine("Duplicate Removed:");
for (i = 0; i < size; i++)
{
Console.WriteLine(numbers[i]);
}
Console.ReadLine();
}
}
}
Every time I go to change the for loops around or add an error message then the program stops deleting the duplicates I am really stumped on this one can someone lend me a hand.
Have a look at LINQ, it has some great functions that can be used for collection manipulation. In your situation I would do the following:
Distinct() here filters the array to only unique values.
int[] initialArray = new int[] { 1, 1, 2, 3, 4, 5 };
int[] noDuplicates = initialArray.Distinct().ToArray(); // [1,2,3,4,5]
I would recommend using a List instead of array. A List will allow you to keep adding entries to it without having to specify the size.
With the list, you can check if entry exists already before adding it, so you wont have to remove or delete
Easy way, use a HashSet
HashSet<int> mySet = new HashSet<int>();
//...
for (i = 0; i < size; i++)
{
Console.WriteLine("Enter number: ");
int number = Convert.ToInt32(Console.ReadLine());
if (!mySet.Add(number))
{
Console.WriteLine("That was a duplicate. Try again");
i--;
}
}
If you must use arrays:
for (i = 0; i < size; i++)
{
Console.WriteLine("Enter number: ");
int numbers = Convert.ToInt32(Console.ReadLine());
if (ExistsInArray(number, numbers))
{
Console.WriteLine("That was a duplicate. Try again");
i--;
}
else
{
numbers[i] = number;
}
}
And then:
private static bool ExistsInArray(number, numbers)
{
// Your code to search numbers for number and return true if found
// Left as an exercise for the OP
}
One important note here is that it's a lot easier to check whether your array already contains the element you are trying to add than to remove it after the fact. If it already exists, just don't add it again.
Well im trying to find a maxValue in a array and its harder then i feel it should. Normally this code here works. If i declare an array and manually put in numbers for the array it find the max value fine. But when i put in a method to make an array with random numbers it breaks and returns the last value set as the maximum one.
static int MaxArray(int[] Array)
{
int maxVal = Array[0];
for(int i = 0; i < Array.Length; i++)
{
if(Array[i] > maxVal)
{
maxVal = Array[i];
}
}
return maxVal;
}
static void Main(string[] args)
{
Random r = new Random();
int[] myArray = new int[5];
for(int i = 0; i < myArray.Length; i++)
{
int rNumb = r.Next(0, 100);
for (int v = 0; v < myArray.Length; v++)
{
myArray[v] = rNumb;
}
Console.WriteLine(myArray[i]);
}
Console.WriteLine("Press entere to find the max value");
Console.ReadKey();
Console.Write(MaxArray(myArray));
Console.Read();
}
The inner for-loop in your Main method is useless. It fills the whole array with the current random number (so at the end the whole array will contain the last random number repeated).
The correct code is the following:
for(int i = 0; i < myArray.Length; i++)
{
int rNumb = r.Next(0, 100);
myArray[i] = rNumb;
Console.WriteLine(myArray[i]);
}
You were overwriting the values with your second for loop,
for (int v = 0; v < myArray.Length; v++)
{
myArray[v] = rNumb;
}
will write the current random number at each index of your array. The last random number will overwrite previous ones, so it will be declared as max since it's the only available number in your array.
Try this instead :
static void Main(string[] args)
{
Random r = new Random();
int[] myArray = new int[5];
for (int i = 0; i < myArray.Length; i++)
{
myArray[i] = r.Next(0, 100);
Console.WriteLine(myArray[i]);
}
Console.WriteLine("Press entere to find the max value");
Console.Write(MaxArray(myArray));
Console.Read();
}
But honestly that MaxArray method is useless, don't reinvent the wheel, use Max from LINQ instead :
Console.Write(myArray.Max());
This is easily achieved using Linq.
using System.Linq;
private static Random _random = new Random();
public static int[] GenerateRandomArray(int arrayLength)
{
return Enumerable.Range(0, arrayLength).Select(i => _random.Next(0, 100)).ToArray();
}
public static int FindMaxValue(int[] array)
{
return array.Max();
}
It's because your array initialization is completely useless. This is what you're looking for:
for(int i = 0; i < myArray.Length; i++)
{
myArray[i] = r.Next(0, 100);
Console.WriteLine(myArray[i]);
}
At the end of it, the array will look like this (with your code):
{n, n, n, n, n}
where n is the last random number.
You don't need this loop. You should change this
for (int v = 0; v < myArray.Length; v++)
{
myArray[v] = rNumb;
}
with
myArray[i] = rNumb;
By writing this loop you are overwriting all the values in the array with the last value.
The reason you get the last value set as the maximum every time is because you set every element in the array to the last random number generated on the last iteration of the outer for loop.
Your Console.WriteLine(myArray[i]); is giving you a false impression of what the values of the array you pass into MaxValue() actually are!
I have 2D jagged array. And I want to sort it by any rows.
I've searched and found code for sorting by columns
private static void Sort<T>(T[][] data, int col)
{
Comparer<T> comparer = Comparer<T>.Default;
Array.Sort<T[]>(data, (x,y) => comparer.Compare(x[col],y[col]));
}
Can I adapt it for sort by any rows ?
Any help is appreciated.
Sample of my jagged array (Added)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
int n = 10;
int[][] capm = new int[3][];
for (int i = 0; i <= 2; i++)
{
capm[i] = new int[n + 1];
}
Random rand = new Random();
for (int i = 1; i <= n; i++)
{
capm[1][i] = i;
}
for (int i = 1; i <= n; i++)
{
capm[2][i] = rand.Next(1, 6);
}
Sort(capm, 2);
Console.ReadLine();
}
private static void Sort<T>(T[][] data, int col)
{
data = data.OrderBy(i => i[col]).ToArray();
}
}
}
#Dani & #Martin I want my jagged array to sort by capm[2][].
The only way I can think of doing this is sorting by an array of indices:
private static void Sort<T>(T[][] data, int row)
{
int[] Indices = new int[data[0].Length];
for(int i = 0; i < Indices.Length; i++)
Indices[i] = i;
Comparer<T> comparer = Comparer<T>.Default;
Array.Sort(Indices, (x, y) => comparer.Compare(data[row][x], data[row][y]);
for(int i = 0; i < data.Length; i++)
{
T[] OldRow = (T[])data[i].Clone();
for(int j = 0; j < OldRow.Length; j++)
data[i][j] = OldRow[i][Indices[j]];
}
}
Given you are using a jagged array this will sort it by the 3rd item.. but a 2D array is probably better if you want to guarantee that each row has the same number of columns... If you have an array within the array which doesn't have a 3rd column, this will fail!
private static void Sort<T>(T[][] data, int col)
{
data = data.OrderBy(i => i[col]).ToArray();
}
Edit:
In order to do anything with the new data reference you either need to return it or pass the parameter by reference:
private static void Sort<T>(ref T[][] data, int col)
{
data = data.OrderBy(i => i[col]).ToArray();
}
The array itself isn't sorted, a new sorted array is created