i am trying to compile this code about arrays and classes in visual studio 2010 but i am having problems when running it an error(consoleapplication.Carray does not contain a constructor that takes 0 arguments)is displaying, may someone tell me what wrong i am doing the code only displays and array or is there any way i can do it????
code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
CArray CArray;
CArray nums = new CArray();
for (int i = 0; i <= 49; i++)
nums.insert(i);
nums.displayElements();
}
}
class CArray
{
private int[] arr;
private int upper;
private int numElements;
public CArray(int size)
{
arr = new int[size];
upper = size - 1;
numElements = 0;
}
public void insert(int item)
{
arr[numElements] = item;
numElements++;
}
public void displayElements()
{
for (int i = 0; i <= upper; i++)
Console.Write(arr[i] + " ");
}
public void clear()
{
for (int i = 0; i <= upper; i++)
arr[i] = 0;
numElements = 0;
}
}
}
OK, several problems. One you have a constructor that is requesting the size of the array, and your main program is not feeding that to the constructor. This is also problematic because you are using the size of the array in your displayelements() loop. This won't compile since your constructor takes an argument. You need to, at the very least, change your Main() program so that it feeds the size of your array to the constructor, which you have defined in your class CArray. Change the following:
CArray nums = new CArray(50); //since 50 is the length of your array
you have a constructor in your CArray class that takes an integer as a parameter (int size). You are not passing that value to your CArray class in your main method.
static void Main()
{
int size = 33; //<-- declare an integer "size"
CArray nums = new CArray(size); // <-- make an array with a size of "size", in this case, 33
for (int i = 0; i <= size-1; i++) // <-- fill the integer with "size" numbers
nums.insert(i);
nums.displayElements();
}
i also would not hard code the size in the for loop you posted in your example.
right now you're saying for (int i = 0; i <= 49; i++) which basically ignores the size of the array you are supposed to pass along to the constructor.
if you use the example i've posted, you will always have an array of x elements.
If you leave the i <= 49 bit and your size is , lets say 100, then your displayElements method will print out the numbers from 0 to 49, followed by a whole bunch of 0's. I dont think that's what you want ^^
Related
This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 1 year ago.
dears ,
i had create a method that will retrieve three arrays after filling them using the ref option
the following error is presented "System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'"
the code as below. how I can fix it
namespace ConsoleApp9
{
class Program
{
public static int getarrays(ref string[] patternName, ref int[] loadindex, ref double[] loadFactor)
{
int status = 0;
for (int i = 0; i < 4; i++)
{
patternName[i] = "test";
}
for (int i = 0; i < 5; i++)
{
loadindex[i] = i;
}
for (int i = 0; i < 8; i++)
{
loadFactor[i] = i/10;
}
return status;
}
static void Main(string[] args)
{
string[] ptt = new string[1];
int[] index = new int[1];
double[] factor = new double[1];
getarrays(ref ptt,ref index, ref factor);
}
}
}
Your arrays all have a size of 1, but your loops go to 4, 5 and 8 respectively. Instead, use the Length property of your arrays in your loops:
for (int i = 0; i < patternName.Length; i++)
{
patternName[i] = "test";
}
This is helpful, because the size of your array is only located in one place (at the creation of the arrays).
You are passing arrays with fixed size of 1. Inside your method, you are iterating for 4, 5 and 8 times while your arrays have length of 1. You should make a constants of pttSize, indexSize and factorSize and use them as arrays size and loops length.
You are passing arrays of length 1 to the function and then try to access indices greater than 0.
Adapt your Main method to pass arrays of the correct length:
string[] ptt = new string[4];
int[] index = new int[5];
double[] factor = new double[8];
I am coding chess, and have made a class called BoardObject to store board states, so I can have a list of them, making a history of the game. BoardObject has a field called boardValues, which is a 2D array which stores the values of each square on the board.
In my while loop where the game is played, if the user input passes my validity checks, the move they enter is passed into a method called movePieceTrad. During movePieceTrad, the list boardHistory is changed in some way to update with the move just made. Here's the problem: nowhere in movePieceTrad is boardHistory or any boardObject addressed. I have looked through with ctrl+f, every reference to boardHistory is in the main method.
In the code below, when I debug, lastInBoardHistory2 is different from what lastInBoardHistory1 was before movePieceTrad, but lastInBoardHistory1 also changes when I go through movePieceTrad, which makes no sense once again. What is going on?
lastInBoardHistory1 = boardHistory[boardHistory.Count - 1].getBoardValues();
movePieceTrad(arr[0], arr[1]);
lastInBoardHistory2 = boardHistory[boardHistory.Count - 1].getBoardValues();
Here is the code for the BoardObject class
namespace chess_v1
{
class BoardObject
{
private int[,] boardValues;
public int[,] possibleEnPassants;
public int[,] castlePiecesMoved;
public int turn = 0;
public BoardObject(int[,] squareValues, int[,] pep, int[,]castleInfo, int inputTurn)
{
boardValues = squareValues;
possibleEnPassants = pep;
castlePiecesMoved = castleInfo;
turn = inputTurn;
}
public int[,] getBoardValues()
{
return boardValues;
}
}
}
Alright, I've solved it.
When constructing a BoardObject, I passed in the input 2D arrays and simply set them equal to my field 2D arrays in BoardObject. Since 2D arrays are arrays of references to places in memory rather than self-contained arrays of arrays, this meant that ultimately I was simply passing along the references in my main method board to the fields in each BoardObject. So, when I moved a piece (changing values within the main method's board) the BoardObject, actually every BoardObject, also changed.
The fix is that instead of passing in the reference arrays in the constructor of BoardObject, I pass in the values with nested for loops. I have tested the functionality that was supposed to have worked before this issue, and everything is working great now!
This is the new BoardObject code; I didn't have to change anything outside of this:
namespace chess_v1
{
class BoardObject
{
public int[,] boardValues = new int[8,8];
public int[,] possibleEnPassants = new int[8,2];
public int[,] castlePiecesMoved = new int[2,3];
public int turn = 0;
public BoardObject(int[,] squareValues, int[,] pep, int[,]castleInfo, int inputTurn)
{
for (int i = 0; i < 8; i++)
{
for (int k = 0; k < 8; k++)
{
boardValues[i, k] = squareValues[i, k];
}
}
for (int i = 0; i < 8; i++)
{
for (int k = 0; k < 2; k++)
{
possibleEnPassants[i, k] = pep[i, k];
}
}
for (int i = 0; i < 2; i++)
{
for (int k = 0; k < 3; k++)
{
castlePiecesMoved[i, k] = castleInfo[i, k];
}
}
turn = inputTurn;
}
}
}
I'm C/C++ to C# developer.
I need to do something like below,
#define LEN 20
int data[LEN];
Since C# doesn't support #define, many forums suggests to declare a const variable. A const variable might help me for below, but not for above.
for (int a = 0; a < LEN; a++)
{
x += data[LEN - a - 1];
}
So, how do I use the constant for array declarations as well?
C# lets you create constants of several built-in types using const keyword.
Constants can be numbers, Boolean values, strings, or a null reference.
Here is a small example:
public class Demo {
public const int Length = 20;
public void Main(string[] args) {
var data = new int[Length];
for (var i = 0 ; i != Length ; i++) {
data[i] = 2*i + 3;
}
}
}
Note: C# naming guidelines suggest avoiding all-caps naming.
Actually you should use it for the instantiation of the array:
const int LEN = 20;
int[] data = new int[LEN];
you could do something like this
static readonly int LEN = 20;
static void Main(string[] args)
{
int[] data = new int[LEN];
for (int a = 0; a < LEN; a++)
{
int x = data[LEN];
}
}
please note that that date array will be default initialized to 0.
also, you will get System.IndexOutOfRangeException for int x = data[LEN]; because you are asking for the 20th index and there is no such index in the array
You should not use constants to declare an array length. Also, there are many data structures in C# that allow you to have a dynamic size array/list/dictionary...
I made a lottery program : http://yadi.sk/d/bBKefn9g4OC7s
Here is the whole source code : http://yadi.sk/d/rnQMfrry4O8cu
Random rnd = new Random();
int[] loto;
loto = new int[7];
for (int f = 1; f <= 6; f++) {
loto[f] = rnd.Next(1, 50); // Generating random number between 1-49
for (int h = 1; h < f; h++) {
if (loto[f] == loto[h]) { // Check with other numbers for the case of duplicate
loto[f] = rnd.Next(1, 50); // If there is a duplicate create that number again
}
}
}
This section I'm generating random 6 different numbers between 1-49
Also I'm wondering in this example, are nested loops increase the spontaneity ?
I'm getting 3-4 max, this program wrong or am I so unlucky ?
( note that : that's my first program )
For all guys trying to help me : I'm really beginner on programming(c# yesterday | c++ 3 weeks i guess), and if you guys clarify what you mean in codes it'll be great.
And please not give me extreme hard coding examples( I don't wanna quit c# )
Your method looks unsafe, as get value from Random again in the inner loop does not guarantee that it will return unduplicated value. For low value as 1-49, you can use simple random-picking algorithm like this
var numbers = new List<int>();
for (int i = 1; i <= 49; i++) {
numbers.Add(i);
}
Random r = new Random();
var loto = new int[6];
for (int f = 0; f < 6; f++) {
int idx = r.Next(0, numbers.Count);
loto[f] = numbers[idx];
numbers.RemoveAt(idx);
}
Note that this is far from optimal solution in terms of performance, but if you will run it only once in a few seconds or more so it should be fine.
I think it's correct except for the for loop declaration: remember that arrays in C# are zero-based. Thus the loop should look like this:
for (int f = 0; f < 7; f++)
or even better:
for (int f = 0; f < loto.Length; f++)
Update: I cannot comment the other answers (too less reputation), thus I have to post it here:
#Dan: only one loop is not correct as it is not allowed to have the same number twice in Loto. In his inner loop, 1342 checks if the created random number already exists, so it is not correct to leave it out.
#James: As 1342 just started programming, it is not necessary to use a static field in my opinion. I guess that he or she has his whole code in the Main method so there is no benefit using a static variable.
There are a few issues here - you've got one too many loops for a start, and no comments.
See this (over-commented) example below:
// This is static so we don't recreate it every time.
private static Random _rnd;
static void Main(string[] args)
{
_rnd = new Random();
// You can declare and initialise a variable in one statement.
// In this case you want the array size to be 6, not 7!
Int32[] lotoNumbers = new Int32[6];
// Generate 10 sets of 6 random numbers
for (int i = 0; i < 10; i++)
{
// Use a meaningful name for your iteration variable
// In this case I used 'idx' as in 'index'
// Arrays in c# are 0-based, so your lotto array has
// 6 elements - [0] to [5]
for (Int32 idx = 0; idx < 6; idx++)
{
// Keep looping until we have a unique number
int proposedNumber;
do
{
proposedNumber = _rnd.Next(1, 50);
} while (lotoNumbers.Contains(proposedNumber));
// Assign the unique proposed number to your array
lotoNumbers[idx] = proposedNumber;
}
}
}
You should end up with a 6 element long array with 6 random numbers between 1 and 50 in it.
Hope that helps!
Edit:
It's also well worth taking note of James' answer - if you're doing the above in a loop, you'll get the same values every time from Random, due to how the seed is used. Using a static version of Random will give much better results.
You don't want to keep re-creating a new instance of Random each time, that's the likely cause of why you keep getting similar values each time. The better approach is to create a static instance of Random and use that across your entire app - this should give you more realistic results e.g.
using System.Collections.Generic;
using System.Linq;
...
static readonly Random rand = new Random();
...
List<int> lottoNumbers = new List<int>(6);
int drawnNumber = -1;
for (int i = 0; i < lottoNumbers.Count; i++) {
do
{
drawnNumber = rand.Next(1, 50); // generate random number
}
while (lottoNumbers.Contains(drawnNumber)) // keep generating random numbers until we get one which hasn't already been drawn
lottoNumbers[i] = drawnNumber; // set the lotto number
}
// print results
foreach (var n in lottoNumbers)
Console.WriteLine(n);
For easily testing it, I have left the console logs and static void main for you.
You do not need two iterations for this. Also - arrays are 0 based, so either f has to be equal to 0, or less than 7. I went with equal 0 below.
I have created a recursive method which creates a new value and checks if the array contains the value. If it does not contain it, it adds it. But if it does contain it, the method calls itself to find a new value. It will continue to do this until a new value is found.
Recursive methods are methods which call themselves. Don't try and fill an array with an index bigger than 50 with this, as you will get an endless loop.
private static readonly Random Rnd = new Random();
static void Main(string[] args)
{
var loto = new int[7];
for (int f = 0; f <= 6; f++)
{
var randomValue = GetRandomNumberNotInArr(loto);
Console.WriteLine(randomValue);
loto[f] = randomValue;
}
Console.Read();
}
/// <summary>
/// Finds a new random value to insert into arr. If arr already contains this another
///random value will be found.
/// </summary>
/// <param name="arr">arr with already found values</param>
/// <returns></returns>
private static int GetRandomNumberNotInArr(int[] arr)
{
var next = Rnd.Next(1, 50);
return !arr.Contains(next) ? next : GetRandomNumberNotInArr(arr);
}
I can see that you are trying to simulate drawing 6 lottery numbers between 1 and 50.
Your code has some logic errors, but rather than fixing it I'm going to suggest doing it a different way.
There are several ways to approach this; a common one is this:
Create an empty collection of numbers.
while there aren't enough numbers in the collection
let randomNumber = new random number in the appropriate range
if (randomNumber isn't already in the collection)
add randomNumber to the collection
But there's another approach which scales nicely, so I'll demonstrate this one (someone else will probably already have written about the other approach):
Add to a collection all the numbers you want to choose from
Randomly rearrange (shuffle) the numbers in the collection
Draw the required number of items from the collection
This is pretty much what happens in a real-life lottery.
To shuffle a collection we can use the Fisher-Yates Shuffle. Here's an implementation:
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
/// <summary>Shuffles the specified array.</summary>
/// <typeparam name="T">The type of the array elements.</typeparam>
/// <param name="array">The array to shuffle.</param>
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1;)
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
private readonly Random _rng = new Random();
}
Here's a full compilable example. I've avoided using Linq in this example because I don't want to confuse you!
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
private static void Main()
{
int[] lotoDraw = createDraw();
Shuffler shuffler = new Shuffler();
shuffler.Shuffle(lotoDraw); // Now they are randomly ordered.
// We want 6 numbers, so we just draw the first 6:
int[] loto = draw(lotoDraw, 6);
// Print them out;
foreach (int ball in loto)
Console.WriteLine(ball);
}
private static int[] draw(int[] bag, int n) // Draws the first n items
{ // from the bag
int[] result = new int[n];
for (int i = 0; i < n; ++i)
result[i] = bag[i];
return result;
}
private static int[] createDraw() // Creates a collection of numbers
{ // from 1..50 to draw from.
int[] result = new int[50];
for (int i = 0; i < 50; ++i)
result[i] = i + 1;
return result;
}
}
public class Shuffler
{
public void Shuffle<T>(IList<T> list)
{
for (int n = list.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = list[n];
list[n] = list[k];
list[k] = temp;
}
}
private readonly Random _rng = new Random();
}
}
I wrote this code and its always showing the same results why?
The code is a searching method.
using System;
using System.Collections.Generic;
using System.Text;
namespace CArraySe
{
class Program
{
class CArray
{
private int[] arr;
private int upper;
private int numElements;
private int compCount;
public CArray(int size)
{
arr = new int[size];
upper = size - 1;
numElements = 0;
compCount = 0;
}
public void Insert(int item)
{
arr[numElements] = item;
numElements++;
}
public void DisplayElements()
{
for (int i = 0; i <= upper; i++)
{
Console.Write(arr[i]);
if (i == upper)
{
Console.WriteLine();
continue;
}
Console.Write(", ");
}
}
public void Clear()
{
for (int i = 0; i <= upper; i++)
arr[i] = 0;
numElements = 0;
}
public bool SeqSearch(CArray n, int sValue)
{
for (int index = 0; index < n.upper; index++)
{
if (arr[index] == sValue)
return true;
}
compCount++;
return false;
}
public int binSearch(CArray n, int value)
{
int upperBound, lowerBound, mid;
upperBound = n.upper; lowerBound = 0;
while (lowerBound <= upperBound)
{
mid = (upperBound + lowerBound) / 2;
if (arr[mid] == value)
return mid;
else if (value < arr[mid]) upperBound = mid - 1;
else lowerBound = mid + 1;
}
compCount++;
return -1;
}
static void Main(string[] args)
{
CArray nums = new CArray(10);
Random rnd = new Random(100);
for (int i = 0; i < 10; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Console.WriteLine();
Console.Write("The Binary Search Result is: ");
Console.WriteLine(nums.binSearch(nums, 500));
Console.WriteLine(nums.compCount);
nums.Clear();
for (int i = 0; i < 10; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Console.Write("The Sequential Search result is: ");
Console.WriteLine(nums.SeqSearch(nums, 500));
Console.WriteLine(nums.compCount);
}
}
}
}
Its always showing the same result even if I changed the number I'm looking for.
The output is:
The Binary Search Result is: -1
1
The Sequential Search result is: False
2
Press any key to continue . . .
I think your value being searched for (500) is not being found. Try outputting the nums array and verifying that what you are looking for is in the array.
Plus, one search returns an int and the other returns a bool. Is there a specific reason for that?
Edit: Also, Binary Search only works with sorted lists.
Your method binSearch returns "-1" when the number isn't found. Since you're populating your array with random values, the odds are very good that the number you search for won't be found. So you're always getting "-1".
To test your binSearch method, you should populate the array with known values, then search for some value that is guaranteed to be in the array.
The first answer is correct. Also, even though you are using a random number, each run of the program will produce the same sequence of random numbers. You should seed it with a different number each time you run the program if you want to test the code well.
As the others have already mentioned, in the general case, there's no guarantee that the number you're searching for is in the list of randomly generated numbers. In the specific case that you posted, the number will never appear in the list because you're generating random numbers in the 0-100 range, then trying to find 500.
Running what you provided does not add a value above 100. If you change your add to this:
for (int i = 0; i < 9; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
nums.Insert(500);
The binSearch returns 9, but the SeqSearch return false because your looping search is index < n.upper and you need to do index <= n.upper to check all values. Additionally, as noted above, the binSearch only works in this case because 500 is larger than all the numbers in the array and has been placed at the last index. The binary search will only work by luck if the list its searching is not sorted. Therefore changing to:
nums.Insert(500);
for (int i = 0; i < 9; i++)
nums.Insert((int)(rnd.NextDouble() * 100));
Will return -1; and true for the SeqSearch.
Although this probably doesn't answer your question directly, here are some observations which makes your code hard to understand and debug:
You need either one of numElements or upper, not both. In Clear(), you are setting only numElements to 0 whereas you are using upper in your loops everywhere?
Binary search works only with sorted arrays
If SeqSearch and BinSearch are receiving an instance of the array, shouldn't they be static methods instead of instance methods?