I have this function that call itself to find all the possible combination with the array of int. The problem is that the program calculate the first combination and then, when the recursion continues, the List of combination still contains that value and i don't understand why.
public static void Permutation(List<int> items, int h, List<int> actualCombination)
{
if (h == actualCombination.Count)
{
results[results.Count] = actualCombination;
}
else
{
for (int i = 0; i < items.Count; i++)
{
actualCombination.Add(items[i]);
List<int> temp = new List<int>(items);
temp.Remove(items[i]);
Permutation(temp, h, actualCombination);
}
return;
}
}
after that, i call the function in main. In my case the second parameter specify the combination length."Results" is a Dictionary composed by int as key and List as value that is used to save all the combination.
static void Main(string[] args)
{
Permutation(new List<int> { 1, 2, 3 }, 3, new List<int>());
Console.ReadKey();
}
I solved the problem by copying the List before of the function add.
Related
I'm following along in a book and trying the 'challenges'. Here I'm running into a problem with properly returning and passing an array between methods. Something goes wrong with returning the array, especially from the second method, and then passing it to third to print.
I understand the stack, heap, values and references on the conceptual level, but something clearly goes
wrong.
Each method appears to work otherwise.
using System;
namespace PracticeArray
{
class Program
{
static int[] GenerateNumbers()
{
Console.WriteLine("Enter a number to generate array from:");
string input = Console.ReadLine();
int inputNumber = Convert.ToInt32(input);
int[] generatedArray = new int[inputNumber];
for (int i = 0; i < generatedArray.Length; i++)
{
generatedArray[i] = i;
}
return generatedArray;
}
static int[] Reverse(int[] arrayToReverse)
{
int count = arrayToReverse.Length;
int[] arrayToReturn = new int[count];
count--;
for (int i = 0; i < arrayToReturn.Length; i++)
{
arrayToReturn[i] = arrayToReverse[count--];
}
return arrayToReturn;
}
static void PrintNumbers(int[] numbersToPrint)
{
foreach (int singleNumber in numbersToPrint)
{
Console.Write(singleNumber + ", ");
}
}
static void Main(string[] args)
{
int[] numbers = GenerateNumbers();
Reverse(numbers);
PrintNumbers(numbers);
}
}
}
The problem
The array you return is a new array:
Take a look in your Reverse function. You create a new array called arrayToReturn and return that array. You also never modify the original input array arrayToReverse.
static int[] Reverse(int[] arrayToReverse) // this input array is never modified
{
int count = arrayToReverse.Length;
// ...
arrayToReturn = new int[count]; // Here is the new array
// ...
return arrayToReturn; // you return the new array
}
Now look at where you called Reverse you passed in some generated numbers, but you ignore the return value of the function so you never find out what the new array is. Remember we already established above that you don't modify the elements of the input array. So numbers will remain unchanged.
static void Main(string[] args)
{
int[] numbers = GenerateNumbers();
Reverse(numbers); // you ignored the return value of `Reverse`
PrintNumbers(numbers); // These are the original unreversed numbers
}
To Fix
Option #1 - New variable to store the result
To fix this, store the array returned from Reverse in a variable and print those numbers.
static void Main(string[] args)
{
int[] numbers = GenerateNumbers();
int[] reversedNumbers = Reverse(numbers);
PrintNumbers(reversedNumbers);
}
Option #2 - Reuse the same variable to store the result
In this option you simply discard the original array by taking the new reversed numbers array returned from Reverse and assigning it to the numbers variable. After that assignment, numbers will refer to the reversed array that was returned from Reverse. The original array is orphaned and forgotten - eventually garbage collected.
static void Main(string[] args)
{
int[] numbers = GenerateNumbers();
// repurpose the `numbers` variable to store the result.
numbers = Reverse(numbers);
PrintNumbers(numbers);
}
I am quite new to programming and I just need help with what I am doing wrong.
This is the code I have so far. Yes, this is for homework, but I am confused on what I have to do next.
In the CreateRandomlyFilledArray method, I have to create an allocated array. This method will take as it's only parameter an integer, The array is then created inside the method, filled with values that have been randomly created by the method. (values can be from 0 to 100).
The array will then be passed (as a parameter) to the PrintArray method, which will take as it's single parameter an array of integers, and will print out everything in the array.
class Returning_An_Array
{
public void RunExercise()
{
ArrayReturnMethods m = new ArrayReturnMethods();
int[] nums1;
nums1 = m.CreateRandomlyFilledArray(10);
m.PrintArray(nums1);
}
}
class ArrayReturnMethods
{
public int[] CreateRandomlyFilledArray( int size )
{
int[] newNums = new int[size];
for (int value = 0; value < newNums.Length; value++)
{
return newNums;
}
return newNums;
}
public void Printarray( int[] value )
{
for(int i = 0; i < value.Length; i++)
{
Console.WriteLine("value is: {0}", value[i]);
}
}
}
Thank you so much!!
Avoid asking homework question here. Especially when a bit of reading would solve your issue. Good luck with your homework. : )
class Program
{
/*
I assume you are trying to
1. Create an array of integers
2. Store random numbers (between 0 and 100) inside that array
3. Print the numbers in the array
You have alot of reading to do as theres alot of fundemental mistakes in both your approach and code.
*/
static void Main(string[] args)
{
// creating an array with random numbers
ArrayMethods m = new ArrayMethods();
int[] nums1;
nums1 = m.CreateRandomlyFilledArray(10);
m.Printarray(nums1);
}
class ArrayMethods
{
/*
- First you have to fill the array with random numbers
In your solution, you have created "CreateRandomlyFilledArray".
1. You created the a new array of integers which is good
2. The way you attempted to fill the new array is incorrect
*/
public int[] CreateRandomlyFilledArray(int size)
{
int[] newNums = new int[size];
Random numGen = new Random(); // This will be used to generate random numbers
for (int elementNum = 0; elementNum < newNums.Length; elementNum++)
{
// here we will put a random number in every position of the array using the random number generator
newNums[elementNum] = numGen.Next(0, 100); // we pass in you minimum and maximum into the next function and it will return a random number between them
}
// here we will return the array with the random numbers
return newNums;
}
/*
- This function prints out each item in an integer array
1. You do not need to a return value as you will not be returning any thing so, Use "void".
*/
public void Printarray(int[] value)
{
for (int i = 0; i < value.Length; i++)
{
Console.WriteLine("value is: {0}", value[i]);
}
}
}
}
Hi guys im trying to learn permutation and recurtion. And im looking for a way how can i use bought at the same time.
MAIN:
namespace Recursive_Permutation
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[5] { 0, 0, 0, 0, 0 };
CalPermutations CP = new CalPermutations();
CP.Run(array, array.Length-1);
}
}
}
Here is my Simple code:
namespace Recursive_Permutation
{
public class CalPermutations
{
public int Run(int[] array,int indexer)
{
if (indexer > array.Length)
{
return 1;
}
else
{
for (int i = 0; i <= array.Length; i++)
{
array[indexer] = i;
Display(array);
}
Run(array, indexer-1);
}
return indexer;
}
public void Display(int[] array)
{
foreach (int num in array)
{
Console.Write(num);
}
Console.WriteLine();
}
}
}
And here is the Output of the program:
Question:
it might be simple to other but im kind of confuse now in how can i manipulate it that it still count the first digit (position [0]) 1 to 5 and go next position and (position 1) and add 1 and go back to [0] and start count again till it reaches 5.
i hope that my explanation is understandable.. thx.
I put together this simpler example of using recursion and permutation. It uses strings internally, but produces the same result.
Its for proof of concept only, since nobody will us recursion for this simple stuff in a professional environment. Recursion can have a big memory impact, but makes describing some problems in a simple way possible.
If I had to choose between iterative and recursive solutions, I would take the iterative one most of the time.
// Main entrance
public void DoStuff()
{
// define variations
List<string> possibilities = new List<string>() { "0", "1", "2", "3", "4", "5" };
// resultlist, will be filled later
List<string> permutations = new List<string>();
// how many values will be taken from the possibilities
int digits = 5;
//do the work
Permute(permutations, possibilities, digits, "");
// display the work
foreach (var item in permutations)
{
Console.WriteLine(item);
}
}
/// <summary>
/// generates a List of permuted strings
/// </summary>
/// <param name="permutations">resultlist</param>
/// <param name="possibilities">possible values of the digit</param>
/// <param name="digitsLeft">how many digits shall be appended</param>
/// <param name="current">the current value of the unfinished result</param>
private void Permute(List<string> permutations, List<string> possibilities, int digitsLeft, string current)
{
// uncomment to see how it works in detail
//Console.WriteLine("step:"+current);
// most important: define Stop conditions for the recursion
// safety stop
if (digitsLeft < 0)
{// end of digits :), normally we never end up here
return;
}
// normal stop
if (digitsLeft == 0)
{// normal endpoint, add the found permutation to the resultlist
permutations.Add(current);
return;
}
// now prepare the recursion, try each possibility
foreach (var item in possibilities)
{
// digitsLeft need to be decreased, since we add a concrete digit to the current value (current+item)
// important: (current + item) generates a new string in memory, the old values won't be touched, permutations possibilities are references, so no memory impact here
Permute(permutations, possibilities, digitsLeft - 1, current + item);
}
}
Update: added comments on each method as per comment.
public class Program
{
public static void Main(string[] args)
{
int[] array = new int[] { 0, 0, 0, 0, 0};
CalPermutations CP = new CalPermutations();
CP.Run(array, 0);
}
}
public class CalPermutations
{
// Prints all the permutations of array, starting at the specified index.
public void Run(int[] array, int indexer)
{
if (indexer < 0 || indexer >= array.Length)
return;
// Keep [0, indexer] combination constant, change combination on right i.e. (indexer, Array.length).
Run(array, indexer+1);
// All the elements on right have finished, increment current element.
array[indexer]++;
// Check if current combination is STILL valid.
if(array[indexer] <= array.Length)
{
// since current combination is still valid, display it, and execute the process again on the new combination.
Display(array);
Run(array, indexer);
}
else
{
// Since current element is out of range, reset it.
array[indexer] = 1;
}
}
// Prints all the elements in array.
public void Display(int[] array)
{
foreach (int num in array)
Console.Write(num);
Console.WriteLine();
}
}
I want to find range between closest value of this elements.
Delta value between elements. And it would be positive number because its modulus.
class Element {
double DeltaValue;
double ElementValue;
public Element(double n) {
ElementValue = n;
}
static void Main() {
list<Element> ListElements = new list<Elements>;
ListElements.Add(3);
ListElements.Add(10);
ListElements.Add(43);
ListElements.Add(100);
ListElements.Add(30);
ListElements.Add(140);
for(int i = 0; i < ListElements.Count; i++) {
ListElements[i].DeltaValue = //and problem is here
//example as for ListElements[2].DeltaValue will be 13; because 43-30=13;
}
//example as for ListElements[2].DeltaValue will be 13; because 43-30=13;
Just sort the array in increasing order and the smallest difference between the previous and the next element of the current element will solve your problem. Here for last element you can just look at the difference of its previous element.
Should be able to do it in one line with linq via the following:
public static int GetClosestVal(this int[] values, int place)
{
return values.OrderBy(v => Math.Abs(v - values[place])).ToArray()[1];
}
The following outputs 30
var testArray = new [] {3, 10, 43, 100, 30, 140};
Console.Write(testArray.GetClosestVal(2));
Basically speaking you sort by the absolute difference between each item and the chosen item, then grab the second item in the list since the first will always be the item itself (since n-n=0)
Thus the sorted list should be [43, 30, 20, 3, 100, 140]
I'm not sure, whether I understand your question right. If I have, then the following code snippet can help you:
class Program
{
static void Main(string[] args)
{
Elements ListElements = new Elements();
ListElements.ElementValue.Add(3);
ListElements.ElementValue.Add(10);
ListElements.ElementValue.Add(43);
ListElements.ElementValue.Add(100);
ListElements.ElementValue.Add(30);
ListElements.ElementValue.Add(140);
ListElements.CreateDeltaValues();
for (int i = 0; i < ListElements.DeltaValue.Count; i++)
{
Console.WriteLine("ListElement["+i+"]: " + ListElements.DeltaValue[i]);
//example as for ListElements[2].DeltaValue will be 13; because 43-30=13;
}
Console.ReadKey();
}
}
public class Elements
{
public List<double> DeltaValue = new List<double>();
public List<double> ElementValue = new List<double>();
public void CreateDeltaValues()
{
this.ElementValue.Sort();
for (int i = 1; i < this.ElementValue.Count; i++)
{
var deltaValue = this.ElementValue[i] - this.ElementValue[i-1];
this.DeltaValue.Add(deltaValue);
}
}
}
It's a console application, but this code should work also for other app models.
This code generates the following output:
I am trying to develop an optimization function that will determine which elements in list of doubles when added together will be less than a specified threshold values. The elements can be used multiple times.
For example if my list of elements is
{1,3,7,10}
and my threshold is 20 I would expect my result to be
1
3
7
10
10, 10
10, 7
10, 7, 3
10,7,1
10,7,1,1
10,7,1,1,1
7,7
7,7,3
7,7,1
7,7,1,1
7,7,1,1,1
...
I expect that the answer to this question will probably be a recursive call and probably could be found in a textbook, but I don't know how to properly phrase the question to find the answer. Help from this group of experts would be appreciated.
This program works, and seems to be the simplest solution. All results are sorted ascending.
private static final HashSet<ArrayList<Double>> lists =
new HashSet<ArrayList<Double>>(); // all of the combinations generated
private static final double[] elements = {10, 7, 3, 1};
public static void main(String[] args) {
combine(20, new ArrayList<Double>());
for (ArrayList<Double> set : lists) {
System.out.println(set);
}
}
private static void combine(final double limit, ArrayList<Double> stack) {
// iterates through the elements that fit in the threshold
for (double item : elements) {
if (item < limit) {
final ArrayList<Double> nextStack = new ArrayList<Double>(stack);
nextStack.add(item);
// a sort is necessary to let the HashSet de-dup properly
Collections.sort(nextStack);
lists.add(nextStack);
combine(limit - item, nextStack);
}
}
}
This type of combinatoric problem, though, generates many results. If you are more concerned with performance than code readability and simplicity, I can optimize further.
c#:
static void Main(string[] args)
{
Run();
}
static public void Run()
{
Combine(20, new List<Double>());
foreach (List<Double> set in lists)
{
Debug.Print(set.ToString());
}
}
private static HashSet<List<Double>> lists =
new HashSet<List<Double>>(); // all of the combinations generated
private static double[] elements = { 10, 7, 3, 1 };
private static void Combine(double limit, List<Double> stack)
{
// iterates through the elements that fit in the threshold
foreach (double item in elements)
{
if (item < limit)
{
List<Double> nextStack = new List<Double>(stack);
nextStack.Add(item);
// a sort is necessary to let the HashSet de-dup properly
nextStack.Sort();
lists.Add(nextStack);
Combine(limit - item, nextStack);
}
}
}
I'm not sure if the Sort() is needed for detecting correctly duplicate entries but this code should work:
private List<int[]> CombinedElementsInArrayLessThanValue(int[] foo, int value)
{
List<int[]> list = new List<int[]>();
for (int i = 0; i < foo.Length; i++)
{
List<int> start = new List<int>();
start.Add(foo[i]);
start.Sort();
int[] clone = start.ToArray();
if (start.Sum() < value && !list.Contains(clone))
{
list.Add(clone);
CombinedElementsInArrayLessThanValue(foo, value, start, list);
}
}
return list;
}
private void CombinedElementsInArrayLessThanValue(int[] foo, int value, List<int> partial, List<int[]> accumulate_result)
{
for (int i = 0; i < foo.Length; i++)
{
List<int> clone = new List<int>(partial);
clone.Add(foo[i]);
clone.Sort();
int[] array = clone.ToArray();
if (clone.Sum() < value && !accumulate_result.Contains(array))
{
accumulate_result.Add(array);
CombinedElementsInArrayLessThanValue(foo, value, clone, accumulate_result);
}
}
}
Process one item in the list at a time, and let the recursion handle one item completely in order to shorten the "depth" of the recursion.
public static List<int[]> Combine(int[] elements, int maxValue)
{
LinkedList<int[]> result = new LinkedList<int[]>();
List<int> listElements = new List<int>(elements);
listElements.Sort();
Combine(listElements.ToArray(), maxValue, new int[0], result);
return result.ToList();
}
private static void Combine(int[] elements, int maxValue, int[] stack, LinkedList<int[]> result)
{
if(elements.Length > 0 && maxValue >= elements[0])
{
var newElements = elements.Skip(1).ToArray();
for (int i = maxValue / elements[0]; i > 0; i--)
{
result.AddLast(stack.Concat(Enumerable.Repeat(elements[0], i)).ToArray());
Combine(newElements, maxValue - i*elements[0], result.Last(), result);
}
Combine(newElements, maxValue, stack, result);
}
}