First array is filled randomly, its length is set from the console .I have an array in which I need to write a sub-array of repeating numbers and the number of repeating numbers. For example {3 3 3 3 3 4}, 3 3 3 3 is the repeating numbers, 4 is their number.
The problem is that if there are repeating numbers at the end of the array, the loop doesn't output them and if I enter the debug mode, I can see that not all numbers are written. What could be the problem?
for (int i = 1; i < array.Length; i++)
{
if (array[i - 1] == array[i])
{
if((i + 1) != array.Length)
{
duplicateCount++;
addArray = array[i - 1];
duplicate += addArray + " ";
}
else
{
duplicateCount++;
lastElement = array[i - 1];
duplicate += lastElement;
}
}
else
{
if (duplicateCount != 1)
{
addPrevious = array[i - 1];
duplicate += addPrevious + " ";
duplicateArrays.Add(duplicate + duplicateCount);
duplicate = "";
duplicateCount = 1;
}
else
{
duplicateCount = 1;
}
}
}
duplicateArrays.Add(duplicate + duplicateCount);
While the Antidisestablishmentarianism code is the shortest one, it uses '^' which is index from end operator introduced in C# 8.0. I'm not carping about that but it's a difference worth knowing. Compiling the same code in the older version will generate a compile time exception. I'll be giving a long yet beginner friendly code which is pretty self-explanatory if you read it twice.
static void Main(string[] args)
{
int[] RandomArray = new int[] { 1, 2, 2, 3, 4, 4, 3, 1, 5, 2, 9, 8, 9, 8, 8, 5, 3, 4, 1 };
int RandomArrayLength = RandomArray.Length;
List<int[]> SubArrayList = new List<int[]>();
List<int> visited = new List<int>();
for (int i = 0; i < RandomArrayLength; i++)
{
int elem = RandomArray[i];
if (!visited.Contains(elem))
{
visited.Add(elem);
List<int> templist = new List<int>();
for (int j = 0; j < RandomArrayLength; j++)
{
if (elem == RandomArray[j])
{
templist.Add(elem);
}
}
if (templist.Count > 1) //You can remove this condition if you want to include all the elements
{
int elemCount = templist.Count;
List<int> sublist = new List<int>();
sublist.AddRange(templist);
sublist.Add(elemCount);
SubArrayList.Add(sublist.ToArray());
}
}
else
{
continue;
}
}
int SubArrayListCount = SubArrayList.Count;
for (int i = 0; i < SubArrayListCount; i++)
{
int[] SubArr = SubArrList[i];
int SubArrCount = SubArr.Length;
for (int j = 0; j < SubArrCount; j++)
{
Console.Write(SubArr[j].ToString() + " ");
}
Console.WriteLine();
}
}
Related
So, I needed to find all the index of elements from an array whose sum is equal to N.
For example : Here I want to find indexes whose sum should be equal to 10.
Input : int[] arr = { 2, 3, 0, 5, 7 }
Output: 0,1,3
If you add indexes arr[0] + arr[1] + arr[3] then 2 + 3 + 5 = 10.
I have tried this, but I am running 3 for loops and 3 if conditions, Can we write this in less code, I want to reduce code complexity.
PS: Post suggestions, not codes..
public static void Check1()
{
int[] arr = { 2, 3, 0, 5, 7 };
int target = 10; int total = 0;
bool found = false;
List<int> lst = new List<int>();
for (int i = 0; i < arr.Length; i++)
{
if (!found)
{
for (int j = i + 1; j < arr.Length; j++)
{
if (!found)
{
total = arr[j] + arr[i];
for (int k = j + 1; k < arr.Length; k++)
{
if (total + arr[k] == target)
{
found = true;
Console.WriteLine($"{i}, {i + 1}, {k}");
break;
}
}
}
}
}
}
Console.ReadLine();
}
I want to write a program that finds the longest sequence of equal elements in an array of integers. If several longest sequences exist, we should print the leftmost one. e.g. Input: 0 1 1 5 2 2 6 3 3
Output: 1 1
I know that my code doesn't work correctly, but I don't know how to fix it. I should solve the problem using only arrays because I don't know how to use lists.
int[] numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();
for (int i = 0; i < numbers.Length; i++)
{
int[] currentSequenceOfEqualElements = new int[numbers.Length];
for (int j = i + 1; j < numbers.Length; j++)
{
if (numbers[i] == numbers[j])
{
if (currentSequenceOfEqualElements[0] == 0)
{
currentSequenceOfEqualElements[0] = numbers[i];
currentSequenceOfEqualElements[1] = numbers[i];
}
else
{
currentSequenceOfEqualElements[i + 2] = numbers[i];
}
}
else
{
break;
}
}
Console.WriteLine(string.Join(' ', currentSequenceOfEqualElements));
}
I will be very grateful if you can explain to me how to do it.
Here is the solution using the MoreLinq library (https://morelinq.github.io/) that mjwills suggested.
Once you get used to linq and morelinq methods the code is easier to understand than custom algo with nested loops and if.
var numbers = new int[]{ 0, 1, 1, 5, 2, 2, 6, 3, 3};
var result = numbers.GroupAdjacent(x => x)
.MaxBy(x => x.Count())
.FirstOrDefault();
foreach (var i in result)
{
Console.Write($"{i} ");
}
Here's a simple solution, using only loops and no linq. It should be nice and easy to understand.
int[] numbers = new[] { 0, 1, 1, 5, 2, 2, 6, 3, 3 };
// Some variables to keep track of the sequence we're currently looking
// at, and the longest sequence we've found so far. We're going to start
// the loop at the 2nd number, so we'll initialize these as if we've
// already processed the first number (which is 0, so we've seen the
// first number of a sequence of 0's).
// Number of numbers in the current sequence
int count = 1;
// Number which is part of the longest sequence so faar
int longestNum = numbers[0];
// Number of numbers in the longest sequence we've seen so far
int longestCount = 1;
for (int i = 1; i < numbers.Length; i++)
{
// We're starting a new sequence
if (numbers[i] != numbers[i-1])
{
count = 0;
}
count++;
// Have we just found a new longest sequence?
if (count > longestCount)
{
longestCount = count;
longestNum = numbers[i];
}
}
// longestNum = 1 and longestCount = 2 (because the longest sequence
// had 2 1's in it). Turn this into the string "1 1".
Console.WriteLine(
string.Join(" ", Enumerable.Repeat(longestNum, longestCount)));
// If you wanted to end up with an array containing [1, 1], then:
int[] result = new int[longestCount];
Array.Fill(result, longestNum);
I will illustrate a recursive answer for your question, below is the code, I kept some if-else statements that there is no need to have them, but at least the code shows the idea.
The code has a basic method that should be exposed as public and a private recursive method that does the heavy lifting. The longest sequence is the empty array(list)
var longSequenceEqualElem = new List<int>();
Later on the recursion, you pass all the elems of the array through all the recursion calls to keep querying the positions, the pos parameter indicates the position level of the recursion.
if (pos < elems.Length) //stop the recursion here, the position will fall out of the indexes of the array, just return what you have in sequence that should be the longest.
The following statement if (sequence.Contains(elems[pos])) means that you found the same number you were carrying on the sequence in the position pos, so you can add it to the sequence and call the recursion with the adjacent position(pos + 1)
If the element in position pos is not part of the sequence you had, then you need to call the recursion with a new sequence containing elems[pos] and later compare the result of that recursion call with the sequence you had to see which of them is the longest one.
Hope this helps
class Program
{
static void Main(string[] args)
{
var elemts = new int[] { 0, 1, 1, 5, 2, 2, 6, 3, 3 };
var result = LongestSequence(elemts);
foreach (var i in result)
{
Console.Write(i + "\t");
}
Console.ReadLine();
}
public static int[] LongestSequence(int[] elems)
{
var longSequenceEqualElem = new List<int>();
return LongestSequenceRec(elems, longSequenceEqualElem, 0);
}
private static int[] LongestSequenceRec(int[] elems, List<int> sequence, int pos)
{
if (pos < elems.Length)
{
if (sequence.Contains(elems[pos]))
{
sequence.Add(elems[pos]);
return LongestSequenceRec(elems, sequence, pos + 1);
}
else
{
var newSeq = LongestSequenceRec(elems, new List<int> { elems[pos] }, pos + 1);
return (newSeq.Length > sequence.Count) ? newSeq.ToArray() : sequence.ToArray();
}
}
return sequence.ToArray();
}
}
static void Main()
{
int[] array1 = new int[9] {0, 1, 1, 5, 2, 2, 6, 3, 3};
int[] array2 = new int[9] {0, 0, 0, 0, 0, 0, 0, 0, 0};
int max_count = 1;
int tempCount = 1;
int num = 0;
for (int i = 0; i < array1.Length - 1; i++)
{
if (array1[i] == array1[i + 1]) tempCount++;
else tempCount = 1;
if (tempCount > max_count)
{
max_count = tempCount;
num = array1[i];
}
}
for (int i = 0; i < max_count; i++) array2[i] = num;
for (int i = 0; i < max_count; i++) Console.Write(array2[i] + " ");
Console.ReadKey();
}
For example we have an array like
{9,8,7,9,5,4,10,3,12}
Now the decreasing sequences are
9,8,7 => 9+8+7 = 24
9,5,4 => 9+5+4 = 18
10,3 => 10+3 =13
12 => 12
In the above summation 24 is the highest and we have to print that value as the result.
Built in functions like array list should not be used
Need a dynamic answer and the answer must satisfy all the other arrays of this type
The code I used is
int[] arr2 = new int[8] { 10, 9, 8, 9, 7, 6, 11, 5 };
int temp2 = 0;
for (int i = 1; i <= arr2.Length - 1; i++)
{
for (int j = i - 1; j <= arr2.Length - 1; j++)
{
if (arr2[j] > arr2[i])
{
temp2 = temp2 + arr2[i]+arr2[j];
}
}
}
Basic, unoptimized:
int[] arr = { 9, 8, 7, 9, 5, 4, 10, 3, 12 };
int maxSum = 0;
int curSum = 0;
for(int i = 0; i < arr.Length; i++)
{
// new sequence
if(curSum == 0)
{
curSum = arr[i];
}
// seqence decreasing
else if(arr[i] <= arr[i - 1])
{
curSum += arr[i];
}
// end of sequence
else
{
// check if the sequence produced a greater sum
if(maxSum < curSum)
{
maxSum = curSum;
}
Console.WriteLine(curSum);
curSum = arr[i];
}
}
Console.WriteLine(curSum);
// final check
if(curSum > maxSum)
{
maxSum = curSum;
}
Console.WriteLine($"Max: {maxSum}");
I haven't tested this but I think it will give you a general idea of how to proceed.
public int FindMaxDecreasing(int[] arr)
{
//Store the max value
var max = 0;
//The current running total
var temp = 0;
//Store the previous value
var previous = 0;
for(int i = 0; i < arr.Length; i++)
{
//Check if first element or decreasing value
if(i == 0 += arr[i] < previous)
{
//Add to temp if it is
temp += arr[i];
}
else
{
//Swap out max value if temp is larger
if(temp > max)
{
max = temp;
}
//Restart temp
temp = arr[i];
}
//Assign previous
previous = arr[i];
}
if(temp > max)
{
max = temp;
}
return max;
}
The prompt is to find the maximal sequence of consecutive equal elements in an array. I don't know what I'm doing wrong but I can't get the right result to show up. :/ Maybe the problem is in the way I iterate with the second loop?
class Class2
{
static void Main(string[] args)
{
int pos=0, bestpos=0, bestlen = 0;
int len = 1;
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
for(int i = 0; i < vargu.Length-1; i++)
{
if (vargu[i] == vargu[i++])
{
len++;
if (len > bestlen)
{
bestlen = len;
bestpos = pos;
}
}
else
{
len = 1;
pos = i++;
}
}
for(int k = bestpos; k <= bestlen; k++)
{
Console.Write("{0}", vargu[k]);
}
Console.ReadLine();
}
}
3 problems.
if (vargu[i] == vargu[i++])
dont use ++ with i, it means increment the actual value of i, and you are looping i. Use "i+1" instead.
pos = i++;
same problem here. the array wont get traversed by each index due to this line.
for(int k = bestpos; k <= bestlen; k++)
k < bestlen + bestpos, because bestpos = 8, and bestlen = 4, so loop run condition fails.
int pos = 0, bestpos = 0, bestlen = 0;
int len = 1;
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
for (int i = 0; i < vargu.Length - 1; i++)
{
if (vargu[i] == vargu[i+1])
{
len++;
if (len > bestlen)
{
bestlen = len;
bestpos = pos;
}
}
else
{
len = 1;
pos = i+1;
}
}
for (int k = bestpos; k < bestlen + bestpos; k++)
{
Console.Write("{0} ", vargu[k]);
}
Console.ReadLine();
You're using i++ in the loop body when you mean i + 1.
Note that i++ has the side effect of increasing i by 1. Leave the incrementation of i solely in for (int i = 0; i < vargu.Length - 1; i++).
Your problem is 2-fold.
First i++ increments the variable i which shifts the index forward. Something that you don't want. You need to use i+1 if you want to access the consecutive element
Second, when you print in the second loop your array the end-index is wrong. You start at bestpos but you want to end at bestpos + bestlen! Since you measure the length of the sequence and don't save the final index.
This should give you the expected result:
int pos = 0, bestpos = 0, bestlen = 0;
int len = 1;
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
for (int i = 0; i < vargu.Length - 1; i++)
{
if (vargu[i] == vargu[i+1])
{
len++;
if (len > bestlen)
{
bestlen = len;
bestpos = pos;
}
}
else
{
len = 1;
pos = i+1;
}
}
for (int k = bestpos; k <= bestpos+bestlen; k++)
{
Console.Write("{0}", vargu[k]);
}
Console.ReadLine();
I would suggest making a structure to hold results :
struct ResultItem
{
public int start;
public int end;
public int value;
}
And then just iterate and compare when signs are changing :
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
List<ResultItem> _result = new List<ResultItem>();
ResultItem current = new ResultItem{ value = vargu[0], start = 0, end = 1 };
for (int i = 1; i < vargu.Length; i++)
{
if (vargu [i] != current.value)
{
current.end = i;
_result.Add( current );
current = new ResultItem { value = vargu[i], start = i, end = i };
}
Console.WriteLine(current.value + " " + current.start + " " + current.end);
}
current.end = vargu.Length;
_result.Add(current);
Then you can dump the result as such :
foreach(ResultItem value in _result)
{
Console.WriteLine("integer {0} was placed {1} times in a row", value.value, value.end - value.start);
}
which should result in something like :
integer 2 was placed 2 times in a row
integer 3 was placed 1 times in a row
integer 4 was placed 1 times in a row
integer 5 was placed 3 times in a row
integer 6 was placed 1 times in a row
integer 9 was placed 4 times in a row
Then to find the longest sequence you can use Linq : _result.Max(r => r.end - r.start);
I've been working on the same problem myself. I tried using Mong Zhu's code above and it almost worked so I tweaked two things and it seemed to work.
Change (vargu[i] == vargu[i+1]) to (vargu[i] + 1 == vargu[i+1])
And pos = i + 1; to pos = i; and it seemed to work. My first post. I hope it's okay.
int[] arr = { 1, 2, 3, 5, 4, 3, 3, 4, 5, 6, 5, 4, 5, 6, 7, 8, 7, 5, 6, 9, 8, 7, 0 };
int pos = 0, bestPos = 0, bestLen = 0;
int len = 1;
for(int i = 0; i < arr.Length -1; i++)
{
if(arr[i] + 1 == arr[i + 1])
{
len++;
if(len > bestLen)
{
bestLen = len;
bestPos = pos;
}
}
else
{
len = 1;
pos = i ;
}
}
for( int k = bestPos; k <= bestLen + bestPos; k++)
{
Console.Write("{0}", arr[k]);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int finalbestsum = 0;
int bestsum = 0;
int bestcount = 0;
int count = 0;
int consval = 0;
int? consval1 = null;
string bestvalue = null;
string bestvalue1 = null;
Console.WriteLine("Enter number of columns for the array");
int col = int.Parse(Console.ReadLine());
Console.WriteLine("Enter number of rows for the array");
int row = int.Parse(Console.ReadLine());
int[,] twodimen = new int[row, col];
for (int index = 0; index < twodimen.GetLength(0); index++ )
{
for (int index1 = 0; index1 < twodimen.GetLength(1); index1++)
{
Console.WriteLine("Enter twodimen {0} {1} value",index, index1);
twodimen[index, index1] = int.Parse(Console.ReadLine());
}
}
for (int index = 0; index < twodimen.GetLength(0); index++ )
{
for (int index1 = 0; index1 < twodimen.GetLength(1)-1; index1++)
{
consval = twodimen[index,index1];
if (consval == twodimen[index, index1 + 1])
{
consval1 = twodimen[index,index1+1];
//Console.Write("{0}" + " ", consval);
bestvalue = bestvalue + Convert.ToString(" " + consval + " ");
count++;
bestsum = bestsum + consval;
}
else if (consval1 != null)
{
//Console.Write(consval1);
count++;
bestvalue = bestvalue + Convert.ToString(" " + consval1 + " ");
bestsum = bestsum + Convert.ToInt16(consval1);
Console.WriteLine();
if (bestcount < count)
{
bestvalue1 = bestvalue;
bestcount = count;
finalbestsum = bestsum;
}
else if (bestcount == count && finalbestsum < bestsum)
{
bestvalue1 = bestvalue;
bestcount = count;
finalbestsum = bestsum;
}
bestvalue = null;
count = 0;
bestsum = 0;
consval1 = null;
}
if (consval == twodimen[index, index1 + 1] && index1 == (twodimen.GetLength(1)-2))
{
bestvalue = bestvalue + Convert.ToString(" " + consval1 + " ");
//Console.Write(consval1);
bestsum = bestsum + Convert.ToInt16(consval1);
count++;
consval1 = null;
if (bestcount < count)
{
bestcount = count;
bestvalue1 = bestvalue;
finalbestsum = bestsum;
}
else if (bestcount == count && finalbestsum < bestsum)
{
bestvalue1 = bestvalue;
bestcount = count;
finalbestsum = bestsum;
}
}
}
bestvalue = null;
count = 0;
bestsum = 0;
Console.WriteLine();
//Console.WriteLine(bestcount);
}
Console.WriteLine(bestvalue1);
Console.ReadLine();
}
}
}
I have an array {1,2,3,4,5,6,7,8,9,10} and I have to find all combinations of k elements from array and k will be dynamic. So for 4 elements below code is sufficient but i have to make this dynamic means,it is not fixed that how many for loops will be used, so please suggest some solution for this.
for (i = 0; i < len - 3; i++)
{
for (j = i + 1; j < len - 2; j++)
{
for (y = j + 1; y < len - 1; y++)
{
for (k = y + 1; k < len; k++)
Console.WriteLine("{0},{1},{2},{3}", s[i], s[j],s[y], s[k]);
}
}
}
All you need is to replace i, j, y, ... with array and manually unroll the for loops like this
static void PrintCombinations(int[] input, int k)
{
var indices = new int[k];
for (int pos = 0, index = 0; ; index++)
{
if (index <= input.Length - k + pos)
{
indices[pos++] = index;
if (pos < k) continue;
// Consume the combination
for (int i = 0; i < k; i++)
{
if (i > 0) Console.Write(",");
Console.Write(input[indices[i]]);
}
Console.WriteLine();
pos--;
}
else
{
if (pos == 0) break;
index = indices[--pos];
}
}
}
You can use this methods for generating combinations of size l
public static List<List<T>> GenerateCombinations<T>(List<T> items, int l)
{
if (l == 0)
return new List<List<T>> { new List<T>() };
var allCombs = new List<List<T>>();
for (int i = 0; i < items.Count(); i++)
{
var listWithRemovedElement = new List<T>(items);
listWithRemovedElement.RemoveRange(0, i + 1);
foreach (var combination in GenerateCombinations(listWithRemovedElement, l - 1))
{
var comb = new List<T>(listWithRemovedElement.Count + 1);
comb.Add(items[i]);
comb.AddRange(combination);
allCombs.Add(comb);
}
}
return allCombs;
}
You can use this methods for generating permutations of size l
public static List<List<T>> GeneratePermutations<T>(List<T> items, int l)
{
if (l == 0)
return new List<List<T>> { new List<T>() };
var allCombs = new List<List<T>>();
for (int i = 0; i < items.Count(); i++)
{
var listWithRemovedElement = new List<T>(items);
listWithRemovedElement.RemoveAt(i);
foreach (var combination in GeneratePermutations(listWithRemovedElement, l - 1))
{
var comb = new List<T>(listWithRemovedElement.Count + 1);
comb.Add(items[i]);
comb.AddRange(combination);
allCombs.Add(comb);
}
}
return allCombs;
}
Permutationsof { 1, 2, 3 } with size of 2
var result = GeneratePermutations(new List<int>() { 1, 2, 3 }, 2);
foreach (var perm in result)
Console.WriteLine(string.Join(",", perm));
1,2
1,3
2,1
2,3
3,1
3,2
Combinations of { 1, 2, 3 } with size of 2
var result = GenerateCombinations(new List<int>() { 1, 2, 3 }, 2);
foreach (var comb in result)
Console.WriteLine(string.Join(",", comb));
1,2
1,3
2,3
This isn't how I'd do it in "real life", but since this seems to be a simple homework-style problem aimed at getting you to use recursion and with the aim of simply writing out the combinations, this is a reasonably simple solution:
class Program
{
public static void Main()
{
int[] test = { 1, 2, 3, 4, 5 };
int k = 4;
WriteCombinations(test, k);
Console.ReadLine();
}
static void WriteCombinations(int[] array, int k, int startPos = 0, string prefix = "")
{
for (int i = startPos; i < array.Length - k + 1; i++)
{
if (k == 1)
{
Console.WriteLine("{0}, {1}", prefix, array[i]);
}
else
{
string newPrefix = array[i].ToString();
if (prefix != "")
{
newPrefix = string.Format("{0}, {1}", prefix, newPrefix);
}
WriteCombinations(array, k - 1, i + 1, newPrefix);
}
}
}
}
If having optional parameters is not "basic" enough, then you can either take away the default values and pass in 0 and "" on the first call, or you can create another "wrapper" method that takes fewer parameters and then calls the first method with the defaults.