Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
This is how my class is designed:
class MergeSort
{
int[] mArray;
public MergeSort(int[] A)
{
mArray = A;
}
void Merge(int[] A,int p ,int q, int r)
{
int n1 = q - p + r;
int i = 0, j = 0;
int n2 = r - q;
int[] left = new int[n1+1];
int[] right = new int[n2+1];
for ( i = 0; i < n1; i++)
left[i] = A[p + i - 1];
for ( i = 0; i < n2; i++)
right[i] = A[q + i];
left[n1] = Int32.MaxValue;
right[n2] = Int32.MaxValue;
i = j = 0;
for (int k = p; k < r; k++)
{
if (left[i] <= right[j])
{
A[k] = left[i];
i++;
}
else
{
A[k] = right[j];
j++;
}
}
}
public void Merge_Sort(int[] A, int p, int r)
{
int q = 0;
mArray = A;
if(p<r)
{
q = (p+r)/2;
Merge_Sort(A,p,q);
Merge_Sort(A, q + 1, r);
Merge(A,p,q,r);
}
}
public string show()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mArray.Length; i++)
{
sb.Append(mArray[i].ToString() + " ");
}
return sb.ToString();
}
}
And this is how i go about sorting:
int[] arr = { 10, 12, 5, 6, 30, 1, 11, 120, 12 };
MergeSort ms = new MergeSort(arr);
ms.Merge_Sort(arr, 0, arr.Length );
MessageBox.Show(ms.show());
But i keep getting the error Index was outside the bounds of the array. on many places in my Merge function. I have tried to implement the algorithm as stated in the book by CLRS(Coremen). But i keep getting this error, i have been at it since 3 days - please help.
You've an error in line left[i] = A[p + i - 1]; because you're passing wrong values for your parameters. Indeed, in that line, p is zero. In the first execution of loop, having i=0 the resulting position in the A array is -1, that causes the IndexOutOfRange exception, as shown below:
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 months ago.
Improve this question
It gives a 1503 error, but I can’t fix it. It gives an error from Array.Sort(
valuePerWeight, weights, values); in the values variable. How can I fix it? I tried to write values in front of weights but it doesn’t work
class Program
{
static void Main(string[] args)
{
int[] data = ReadDataFromFile("items.txt");
int capacity = data[0];
int[] weights = new int[data.Length - 1];
int[] values = new int[data.Length - 1];
for (int i = 1; i < data.Length; i++)
{
weights[i - 1] = data[i];
values[i - 1] = data[++i];
}
int[] selectedItems = GreedyKnapsack(capacity, weights, values);
int totalValue = 0;
Console.WriteLine("Selected items:");
for (int i = 0; i < selectedItems.Length; i++)
{
if (selectedItems[i] == 1)
{
Console.WriteLine($"Weight: {weights[i]}, Value: {values[i]}");
totalValue += values[i];
}
}
Console.WriteLine($"Total value: {totalValue}");
}
it gives an error in array.sort
static int[] GreedyKnapsack(int capacity, int[] weights, int[] values)
{
int n = weights.Length;
int[] selected = new int[n];
double[] valuePerWeight = new double[n];
for (int i = 0; i < n; i++)
{
valuePerWeight[i] = (double)values[i] / weights[i];
}
Array.Sort(
valuePerWeight, weights, values);
int weight = 0;
for (int i = n - 1; i >= 0; i--)
{
if (weight + weights[i] <= capacity)
{
selected[i] = 1;
weight += weights[i];
}
}
return selected;
}
}
}
You are getting CS1503 because you are passing an array of int Values when you should be passing an IComparer<int>.
From you question, it´s not clear what's the objective of your method.
If you want to sort valuePerWeight, weights and values, you can just sort them seperately:
Array.Sort(valuePerWeight)
Array.Sort(weights)
Array.Sort(values)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
I need to get sequential subsets (self-made terminology) for a given set. For instance, if my set is {1,5,8,25}, the output should be:
{1}
{5}
{8}
{25}
{1,5}
{5,8}
{8,25}
{1,5,8}
{5,8,25}
{1,5,8,25}
I tried implementing the same in C# lists using iterative approach but found the time complexity to be high. Can anyone help me with this?
As per comments, here is my approach which is similar to the posted answer:
public static void Main(string[] args)
{
List<int> input = new List<int>() { 0, 1, 2, 3 };
var output = GetSubset(input);
foreach (var element in output)
{
Console.Write("{ ");
foreach (int e in element)
{
Console.Write(e + " ");
}
Console.Write("}");
Console.WriteLine();
}
Console.ReadKey();
}
private static List<List<int>> GetSubset(List<int> arr)
{
List<List<int>> sets = new List<List<int>>();
var length = arr.Count;
// No of element on each set
for (int k = 1; k <= length; k++)
{
for (int i = 0; i <= length - k; i++)
{
List<int> set = new List<int>();
for (int j = i; j < (i + k); j++)
{
set.Add(arr[j]);
}
sets.Add(set);
}
}
return sets;
}
As correctly pointed out, the time complexity is O(n^3). Is there a better approach towards same.
This should sort you out if it's fast enough:
IEnumerable<int[]> GetSequentialSubsets(int[] data)
{
Array.Sort(data);
//The number of elements to add to each returned array
for (int m = 1; m <= arr.Length; m++)
{
//The starting index in int[] data of the current array
for (int i = 0; i <= arr.Length - m; i++)
{
var element = new int[m];
//Adding data to the current array
for (int j = i; j < i + m; j++)
{
element[j - i] = arr[j];
}
yield return element;
}
}
}
Note that I sort the array, just in case you throw in something unsorted. But if you don't care about incrementing elements and just want the elements to be sequential, you should leave that part out. I didn't find that part of your question entirely clear. You can test it like this:
var arr = new[] { 1, 5, 8, 25 };
var res = GetSequentialSubsets(arr);
foreach (var element in res)
{
foreach (int e in element)
{
Console.Write(e + " ");
}
Console.WriteLine();
}
The complexity must be the number of indices we iterate over which is equal to
n * (n + 1) * (n + 2) / 6
so O(n³).
N.B. The number of indices is the sum of i * (n + 1 - i) from i = 1 to i = n. WolframAlpha then gives the result above.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I have this algorithm:
static int findMaxRec(int[] w, int[] v, int W, int n)
{
int max = int.MinValue;
int res;
for (int i = 0; i < n; i++)
{
if (w[i] <= W)
{
if (w[i] == W)
res = v[i]; // F(0) + v[i] = v[i]
else
res = findMaxRec(w, v, W - w[i], n) + v[i];
max = max < res ? res : max;
}
}
return max;
}
How can I convert it to dynamic programming algorithm?
I have tried several ideas but none of them seems to work. So I am stuck.
P.S. w and v are just simple number arrays, nothing fancier. W is just a number. This algorithm does not implement any particular task I just found it in a book where they ask to implement algorithms for given formulas.
UPDATE:
static int findMaxDyn(int[] F, int[] w, int[] v, int W, int n)
{
int max = int.MinValue;
int res;
for (int i = 0; i < n; i++)
{
if (w[i] <= W)
{
if (F[W - w[i]] == int.MinValue) // calculate only if -inf
{
if (w[i] == W)
res = v[i]; // F(0) + v[i] = v[i]
else
res = findMaxDyn(F, w, v, W - w[i], n) + v[i];
max = max < res ? res : max;
F[W - w[i]] = max;
}
}
}
return max;
}
This gives wrong answers that do not match to recursive algorithm. And it seems to still use recursion...
Recursion tree that I have drawn when
int [] w = new []{ 4, 3, 2, 1};
int [] v = new []{ 4, 3, 2, 1};
int W = 4;
int n = 4;
I still don't know what the algorithm is trying to do but the non-recursive function could be:
public static int findMaxRec_NonRecursive(int[] Vect_w, int[] Vect_v, int W, int n)
{
List<int> prevWValues = new List<int>();
List<int> prevVValues = new List<int>();
List<int> prevIndex_i = new List<int>();
List<int> prevMaxValue = new List<int>();
int ListIndex = 0, iniIndex = 0, max = int.MinValue;
startOver:
for (int i = iniIndex; i < n; i++)
{
if (Vect_w[i] <= W)
{
if (Vect_w[i] == W)
max = Math.Max(Vect_v[i], max);
else
{
if (prevWValues.Count > ListIndex)
{
prevWValues[ListIndex] = W;
prevIndex_i[ListIndex] = i;
prevVValues[ListIndex] = Vect_v[i];
prevMaxValue[ListIndex] = max;
}
else
{
prevWValues.Add(W);
prevIndex_i.Add(i);
prevVValues.Add(Vect_v[i]);
prevMaxValue.Add(max);
}
W -= Vect_w[i];
ListIndex++;
iniIndex = 0;
max = int.MinValue;
goto startOver;
}
}
}
if (ListIndex>0)
{
ListIndex--;
iniIndex = prevIndex_i[ListIndex]+1;
W = prevWValues[ListIndex];
max = Math.Max(max+ prevVValues[ListIndex], prevMaxValue[ListIndex]);
goto startOver;
}
return max;
}
Sorry for the 'gotos', I just found it easier to program for this case. Also I have renamed a little your input variables not to drive crazy.
EDIT
As others have pointed out, it could be used as a Knapsack algorithm, so knowing what it is intended to do, you could optimize/simplify a little more (the complexity of these kind of algorithms grow exponentially with n). For instance, you can sort the input Vect_W values and replace lists by arrays.
public static int findMaxRec_NonRecursive(int[] Vect_w, int[] Vect_v, int W, int n)
{
Array.Sort(Vect_w, Vect_v);
n = Math.Min(n, Vect_w.Length);
//Remove here repeated elements in Vect_w selecting the one with higher Vect_v if uniqueness is not assured
int minVectW = Vect_w[0];
int L = W / minVectW + 1;
int[] prevWValues = new int[L];
int[] prevVValues = new int[L];
int[] prevIndex_i = new int[L];
int[] prevMaxValue = new int[L];
int ListIndex = 0, iniIndex = n - 1, max = int.MinValue, PrevUsefullIndex = 0;
startOver:
for (int i = iniIndex; i >= 0; i--)
{
if (Vect_w[i] <= W)
{
if (PrevUsefullIndex < i)
PrevUsefullIndex = i;
if (Vect_w[i] == W)
max = Math.Max(Vect_v[i], max);
else
{
int newW = W - Vect_w[i];
if (newW < minVectW)
max = Math.Max(Vect_v[i], max);
else
{
prevWValues[ListIndex] = W;
prevIndex_i[ListIndex] = i;
prevVValues[ListIndex] = Vect_v[i];
prevMaxValue[ListIndex] = max;
W = newW;
ListIndex++;
iniIndex = PrevUsefullIndex;
PrevUsefullIndex = 0;
max = int.MinValue;
goto startOver;
}
}
}
}
if (ListIndex > 0)
{
ListIndex--;
iniIndex = prevIndex_i[ListIndex] - 1;
W = prevWValues[ListIndex];
max = Math.Max(max + prevVValues[ListIndex], prevMaxValue[ListIndex]);
goto startOver;
}
return max;
}
EDIT 2
I just found out that the initial recursive algorithm posted is not well conditioned, for example in the case where the best branch is the first branch. I think it should have an additional condition to avoid that:
//[...]
else
{
int innerMax = findMaxRec(w, v, W - w[i], n);
if (innerMax == int.MinValue)
innerMax = 0;
res = innerMax + v[i];
}
//[...]
I have also added a condition in the non-recursive algorithm that does pretty much the same by checking if the branch can be officialy closed when the new W is lower than the smallest vect_W element.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
Well I've started doing a project on C#, and it has object (class called CLA). CLA creates a set(list).
I will do function on List<Cla> and which needs HighValue, LowValue and so on. But ArgumentOutOfRangeException got in here.
Can i call method in constructor? Is this code correct?
class Program
{
static void Main(string[] args)
{
List<Cla> ClaList = new List<Cla>();
ClaList.Add(new Cla("a", 10.3, "Priznak1", 1));
ClaList.Add(new Cla("b", 3.3, "Priznak1", 1));
ClaList.Add(new Cla("c", 7.3, "Priznak1", 1));
ClaList.Add(new Cla("d", 9.3, "Priznak1", 1));
ClaList.Add(new Cla("e", 8.3, "Priznak1", 1));
CritListSmall NewTest = new CritListSmall(ClaList);
Console.WriteLine("ddd {0}", NewTest.HighValue);
}
}
class CritListSmall
{
public double HighValue;
public double LowValue;
public CritListSmall(List<Cla> p)
{
HighValue = p[0].ObjectValue;
LowValue = p[0].ObjectValue;
int NumberElements;
NumberElements = p.Count;
for (int i = 1; i <= NumberElements; i++)
{
double m = p[i].ObjectValue; //Exception occurs here
if (HighValue < m)
HighValue = m;
}
for (int l = 1; l <= NumberElements; l++)
{
double n = p[l].ObjectValue; //and here
if (LowValue > n)
LowValue = n;
}
}
public class Cla
{
public string ObjectName;
public double ObjectValue;
public string PriznakName;
public int ClassNumber;
public Cla(string on, double ov, string pn, int cn)
{
ObjectName = on;
ObjectValue = ov;
PriznakName = pn;
ClassNumber = cn;
}
public double CritValue;
public double ExpValue;
public bool Outlier;
public double AbsoluteValue;
}
}
In C# collections have zero-based indexes. It means if you have 5 items in list, their indexes will be 0,1,2,3,4. So instead of
for(int i = 1; i <= NumberElements; i++)
you should use
for(int i = 0; i < NumberElements; i++)
^ ^
from zero and less than count of items
In C# array indexes start at 0, not 1, so you need to change your loops to be this:
for (int i = 0; i < NumberElements; i++)
And:
for (int l = 0; l < NumberElements; l++)
for(int i = 1; i <= NumberElements; i++)
That is your problem. It must be:
for(int i = 0; i < NumberElements; i++)
for(int l = 0; l < NumberElements; l++)
Why? NumberElements is the count of p, for example 10. But the index is from 0 to 9.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm currently doing an assignment where I need to find the errors in a program that is preventing it from executing. Its a comparison sort program where there are two sorting methods being compared, Merge Sort and Counting Sort. Its giving me the "No overload for (insert method), takes 1 arguments" message, but I'm unable to find or fix what's giving it the errors, any general idea or fixes to make the comparison work would be appreciated.
using System;
using System.Collections;
namespace Sort
{
class Program
{
static void Main(string[] args)
{
Random rdm = new Random();
ArrayList data = new ArrayList();
ArrayList dataB = new ArrayList();
int size = 50000;
int[] dta = new int[size];
int[] dta50 = new int[50];
int randomNum;
DateTime startTime, endTime;
int i;
// Show both methods worked
for (i = 0; i < 50; i++)
{
randomNum = rdm.Next(100);
data.Add(randomNum);
dta50[i] = randomNum;
}
dataB = CountingSort(data);
PrintArray("Merge Sort:", dataB);
MergeSort(dta50);
Console.WriteLine();
Console.WriteLine("\nCounting Sort:");
Console.WriteLine();
for (int x = 0; x < 50; x++)
Console.Write(dta50[x] + " ");
Console.WriteLine();
Console.WriteLine("\nCounting Sort\tMerge Sort");
for (int n = 1; n < 20; n++) // run 20 times
{
data.Clear();
for (i = 0; i < size; i++)
{
randomNum = rdm.Next(size);
data.Add(randomNum);
dta[i] = randomNum;
}
// Counting Sorting
startTime = DateTime.Now;
CountingSort(data);
endTime = DateTime.Now;
TimeSpan howlong = endTime.Subtract(startTime);
Console.Write(" {0}ms", howlong.Milliseconds);
// Merge Sorting
startTime = DateTime.Now;
MergeSort(dta);
endTime = DateTime.Now;
TimeSpan howlong1 = endTime.Subtract(startTime);
Console.WriteLine("\t\t{0}ms", howlong1.Milliseconds);
}
Console.ReadLine();
}
public static void MergeSort(int[] input, int left, int right)
{
if (left < right)
{
int middle = (left + right) / 2;
MergeSort(input, left, middle);
MergeSort(input, middle + 1, right);
//Merge
int[] leftArray = new int[middle - left + 1];
int[] rightArray = new int[right - middle];
Array.Copy(input, left, leftArray, 0, middle - left + 1);
Array.Copy(input, middle + 1, rightArray, 0, right - middle);
int i = 0;
int j = 0;
for (int k = left; k < right + 1; k++)
{
if (i == leftArray.Length)
{
input[k] = rightArray[j];
j++;
}
else if (j == rightArray.Length)
{
input[k] = leftArray[i];
i++;
}
else if (leftArray[i] <= rightArray[j])
{
input[k] = leftArray[i];
i++;
}
else
{
input[k] = rightArray[j];
j++;
}
}
}
}
private static int[] CountingSort(int[] arr, int min, int max)
{
int[] count = new int[max - min + 1];
int z = 0;
for (int i = 0; i < count.Length; i++) { count[i] = 0; }
for (int i = 0; i < arr.Length; i++) { count[arr[i] - min]++; }
for (int i = min; i <= max; i++)
{
while (count[i - min]-- > 0)
{
arr[z] = i;
z++;
}
}
return arr;
}
static void PrintArray(string title, ArrayList dt)
{
int cc = 0;
Console.WriteLine("\n" + title + "\n");
foreach (int item in dt)
{
if (cc < 10)
Console.Write("{0,4}", item);
else
{ Console.WriteLine(); cc = 0; }
}
}
}
}
Look at your functions:
public static void MergeSort(int[] input, int left, int right)
private static int[] CountingSort(int[] arr, int min, int max)
They each expect three values when you invoke them. Look at how you invoke them:
MergeSort(dta50);
CountingSort(data);
MergeSort(dta);
You're supplying one value, not three.
Elsewhere you invoke them differently:
MergeSort(input, left, middle);
MergeSort(input, middle + 1, right);
In those cases you supply three values.
You need to supply the functions with the values it requires. Otherwise the code has no way of knowing what to do.