I have two arrays that have 20 randomly assigned elements and I need to create a method that replaces the duplicate numbers in an array with zeros but when I display the output nothing is changed.
This is the method for removing the repeating numbers. Is there a problem with the way the for loop is set up?
public static void RemoveDuplicates (int [] xArray){
for (int i = 0; i > xArray.Length-1; i++){
if (xArray[i] == xArray[i+1])
xArray[i] = 0;
}
}
and this is the whole thing
using System;
class MainClass {
public static void Main (string[] args) {
int [] student1 = new int [20];
int [] student2 = new int [20];
//int [] both = new int [40];
FillArray(student1);
FillArray(student2);
//Console.WriteLine("---------- Unsorted ----------");
//DisplayOutput(student1,student2);
Sort2Arrays(student1,student2);
//Console.WriteLine("---------- Sorted ----------");
//DisplayOutput(student1,student2);
RemoveDuplicates(student1);
RemoveDuplicates(student2);
DisplayOutput(student1, student2);
Sort2Arrays(student1,student2);
Console.WriteLine("---------- 1 and 2 no duplicates ----------");
DisplayOutput(student1, student2);
Console.WriteLine("done");
}//end main
public static void FillArray (int [] xArray){
Random rnd = new Random();
for(int i = 0; i< xArray.Length; i++){
xArray.SetValue (rnd.Next(80, 101),i);
}//end for
}//end FillArray
public static void Sort2Arrays (int [] xArray, int [] yArray){
Array.Sort(xArray);
Array.Sort(yArray);
}//end Sort2Arrays
public static void DisplayOutput (int [] xArray, int [] yArray){
for(int i = 0; i< 20; i++){
Console.WriteLine("{0}-{1}",xArray.GetValue(i),yArray.GetValue(i));
}//end for
}//end DisplayOutput
public static void RemoveDuplicates (int [] xArray){
for (int i = 0; i > xArray.Length-1; i++){
if (xArray[i] == xArray[i+1])
xArray[i] = 0;
}
}
}
Your for-loop condition is wrong, not >:
for (int i = 0; i > xArray.Length - 1; i++){
but <
for (int i = 0; i < xArray.Length - 1; i++)
with your version you will never enter the loop.
May i suggest you a different way to replace the duplicates(what you actually do), which is more efficient, more readable and more reusable:
public static void ReplaceDuplicates<T>(IList<T> xArray, T replaceWith)
{
HashSet<T> set = new HashSet<T>();
for (int i = 0; i < xArray.Count; i++)
{
if(!set.Add(xArray[i]))
{
xArray[i] = replaceWith;
}
}
}
It also doesn't need to sort the collection.
You use it in this way:
ReplaceDuplicates(student1, 0);
ReplaceDuplicates(student2, 0);
the > shouldve been <
public static void RemoveDuplicates (int [] xArray){
for (int i = 0; i < xArray.Length - 2; i++){
if (xArray[i] == xArray[i+1])
xArray[i] = 0;
}//end for
}//end RemoveDuplicates
public static void RemoveDuplicates(int[] array)
{
var foundValues = new HashSet<int>();
for (var index = 0; index < array.Length; index++)
{
var currentValue = array[index];
if (foundValues.Contains(currentValue))
{
array[index] = 0;
}
else
{
foundValues.Add(currentValue);
}
}
}
Related
If I have a method that finds the greatest integer in an array. How do I pass the result back to main?
public static int maxNumber(int[] Array) {
int maxNumber = Array[0];
for (int i = 1; i < Array.length; i++) {
if (List[i] > maxNumber) {
maxNumber = Array[i];
}
return maxNumber;
}
}
Return the result outside the loop, it should be this way
public static int maxNumber(int[] Array)
{
int maxNumber = Array[0];
for (int i = 1; i < Array.length; i++)
{
if (List[i] > maxNumber)
{
maxNumber = Array[i];
}
}
return maxNumber;
}
if you want to get the number as output, call like this
int max = maxNumber(yourArray);
I'm writing a program about reversing an array with 3 methods (GenerateNumber, reverse and PrintOut).
Unfortunately it doesn't run. Can you help me to find the error and fix them?
Why doesn't it run?
public class Program
{
static int[] GenerateNumber()
{
string a = Console.ReadLine();
int b = Convert.ToInt32(a);
int[] number = new int [b];
string[] c = new string[b];
for (int index = 0; index < number.Length; index++)
{
c[index] = Console.ReadLine();
number [index]= Convert.ToInt32(c[index]);
}
return number;
}
static int[] reverse(int[] array)
{
for (int index =0; index <array.Length; index++)
{
int c = array[index];
array[index] = array[array.Length - index - 1];
array[array.Length - index - 1]= c;
}
return array;
}
static int[] PrintOut (int[] array)
{
for (int index = 0; index > array.Length; index++)
Console.Write(array[index]);
return array;
}
static void Main(string[] args)
{
int[] number = GenerateNumber();
reverse(number);
PrintOut(number);
Console.ReadKey();
}
The immediate cause of the misbehaviour is in the
static int[] PrintOut (int[] array)
{
for (int index = 0; index > array.Length; index++) // <- wrong condition
Console.Write(array[index]);
The comparison should be < instead of >:
for (int index = 0; index < array.Length; index++)
A better choice, however, is foreach loop instead of for
foreach (var item in array)
Console.Write(item); // propably, you want WriteLine not Write
Some suggestions:
public class Program {
static int[] GenerateNumber() {
// You don't want "c" array, but "number"
int[] number = new int [Convert.ToInt32(Console.ReadLine())];
for (int index = 0; index < number.Length; index++)
number [index] = Convert.ToInt32(Console.ReadLine());
return number;
}
// Nice implementation, nothing to improve but naming (reverse -> Reverse)
static int[] Reverse(int[] array) {
for (int index = 0; index <array.Length; index++) {
int c = array[index];
array[index] = array[array.Length - index - 1];
array[array.Length - index - 1] = c;
}
return array;
}
static int[] PrintOut (int[] array) {
// foreach is easier to implement and easier to read
foreach (var item in array)
Console.WriteLine(item); // <- you, probably, want WriteLine not Write
return array;
}
static void Main(string[] args) {
int[] number = GenerateNumber();
Reverse(number);
PrintOut(number);
Console.ReadKey();
}
I am getting this NullReferenceException in the second execution of the while loop of the changeColors function.
public class myClass {
Tuple<int,int>[] theArray = new Tuple<int, int>[100];
}
public myClass() {
theArray = null;
}
public Tuple<int,int>[] findRedPixels(){
Tuple<int,int>[] myArray = new Tuple<int, int>[100];
int k = 0;
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if (graph.pixelMap [i, j].color == "red") {
myArray[k]= new Tuple<int,int>(i,j);
k++;
}
}
}
return myArray;
}
public void changeColors(){
while (true) {
theArray = findRedPixels();
foreach (var item in theArray) {
//error appears here in the second time it executes the while loop
Console.WriteLine (item.Item1 );
}
}
}
You should not return array from function findRedPixels as you have done because that array will already be initialized with 100 elements, try using List as it provide you flexibility and you can increase decrease size on fly may be something like this
public Tuple<int,int>[] findRedPixels(){
List<Tuple<int,int>> myArray = new List<Tuple<int, int>>();
int k = 0;
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if( graph.pixelMap [i, j].color=="red"){
myArray.Add( new Tuple<int,int>(i,j));
k++;
}
}
}
return myArray.ToArray();
}
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;
}
}
This is kind of a curiosity question. I do have an existing solution, but I wonder if people know of a better approach.
My callers want to call me with int[][]. I have a routine that needs to process an int**. What's the best way to do this conversion? In other words:
public static void Func1(int[][] data) {
Func2(data); //how to do this?
}
private unsafe static void Func2(int** data) {
//process data
}
Following is the best approach I could come up with. It works fine, but I can't say I'm 100% happy with the recursive approach (and the O(data.Length) stack space it requires)
public static void Main() {
var test=new[] {
new [] {10},
new [] {20,30},
new [] {40,50,60},
new [] {70,80,90,100},
};
MySolution_Func1(test);
}
public unsafe static void MySolution_Func1(int[][] data) {
var items=new int*[data.Length];
Recurse(0, data, items);
}
public unsafe static void Recurse(int index, int[][] data, int*[] build) {
if(index==data.Length) {
fixed(int** finalp=build) {
Func2(finalp);
}
} else {
fixed(int* nextp=data[index]) {
build[index]=nextp;
Recurse(index+1, data, build);
}
}
}
private unsafe static void Func2(int** data) {
for(var j=0; j<4; ++j) {
for(var i=0; i<j+1; ++i) {
Debug.WriteLine("{0},{1}: {2}", j, i, data[j][i]);
}
}
}
There's no need to copy the whole array. You can create an array of pointers (i.e. IntPtr[]), and then cast that to int**. It's not pretty, and I wouldn't suggest doing it. But it can be done. The code below shows how.
int[][] myArray = new int[10][];
for (int i = 0; i < 10; ++i)
{
int[] x = new int[10];
for (int j = 0; j < 10; ++j)
{
x[j] = 10 * i + j;
}
myArray[i] = x;
}
// Output the array
Console.WriteLine("int[][]");
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
Console.Write("{0}, ", myArray[i][j]);
}
Console.WriteLine();
}
// Convert to int*[]
unsafe
{
GCHandle[] handles = new GCHandle[10];
IntPtr[] ArrayOfPointer = new IntPtr[10];
for (int i = 0; i < 10; ++i)
{
handles[i] = GCHandle.Alloc(myArray[i], GCHandleType.Pinned);
ArrayOfPointer[i] = handles[i].AddrOfPinnedObject();
}
// Okay, let's output that
Console.WriteLine("int*[]");
for (int i = 0; i < 10; ++i)
{
int* p = (int*)ArrayOfPointer[i];
for (int j = 0; j < 10; ++j)
{
Console.Write("{0}, ", *p);
++p;
}
Console.WriteLine();
}
// now convert to int**
GCHandle bigHandle = GCHandle.Alloc(ArrayOfPointer, GCHandleType.Pinned);
int** ppInt = (int**)bigHandle.AddrOfPinnedObject();
// and output it
Console.WriteLine("int**");
int** pa = ppInt;
for (int i = 0; i < 10; ++i)
{
int* p = *pa;
for (int j = 0; j < 10; ++j)
{
Console.Write("{0}, ", *p);
++p;
}
Console.WriteLine();
++pa;
}
// Need to free the handles
bigHandle.Free();
for (int i = 0; i < 10; ++i)
{
handles[i].Free();
}
}
public unsafe void ConvertToNative(int[][] jarray, out int** ptr)
{
ptr= (int**)Marshal.AllocHGlobal(jarray.Length*sizeof(int));
for (int i = 0; i < jarray.Length; i++)
{
*(ptr+i) = (int*)Marshal.AllocHGlobal(jarray[i].Length*sizeof(int));
for (int j = 0; j < jarray[i].Length; j++)
{
(*(i + ptr))[j] = jarray[i][j];
}
}
}
This works but uses unmanaged memory, and there is no recursion, is that valid ?
You can do it with O(1) stack space, if you are willing to copy all the data into another buffer:
public unsafe static void AlternateSolution_Func1(int[][] data) {
var buffer=new int[data.Sum(a => a.Length)];
fixed(int* pBuffer=buffer) {
var items=new int*[data.Length];
int count=0;
for(int i=0; i<data.Length; ++i) {
items[i]=pBuffer+count;
var array=data[i];
for(int j=0; j<array.Length; ++j) {
pBuffer[count++]=array[j];
}
}
fixed(int** pItems=items) {
Func2(pItems);
}
}
}