Find Min-Max values of array without using Linq? - c#

I've been working on this assignment for my programming class for a little bit and though I had it solved. A little info for anyone interested: My task is to find the score of the competitor from an array of scores (eg, int[] scores = 4, 5, 6 , 7, 8, 9). BUT I must not include the highest and lowest values when adding the rest of the scores together (eg, score would = 5+6+7+8 (no including 4 and 9)).
My solution when we were allowed to use linq was as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Scoring {
class Program {
static void Main(string[] args) {
int[] scores = { 4, 7, 9, 3, 8, 6 };
remove_duplicates(scores);
console_text(scores);
ExitProgram();
}
static void remove_duplicates(int[] scores) { //removes duplicat values from array
var pScores = scores.Distinct().ToArray();
}
static int result(int[] pScores) { //calculates results by removing max and min scores, then adding the remaining.
return pScores.Sum() - pScores.Max() - pScores.Min();
}
static void console_text(int[] pScores) { //renders the text in the consol window
int final_score = result(pScores);
Console.Write("Competitor your scores were " );
foreach (int i in pScores) {
Console.Write(" " + i);
}
Console.WriteLine("\r\n" + " and your score was " + final_score);
}
static void ExitProgram() {
Console.Write("\n\nPress any key to exit program: ");
Console.ReadKey();
}//end ExitProgram
}
}
So I thought I was done, but now I have recieved and email stating:
"cannot use any system.array methods nor can you use any functionality of Linq or any other library class you may discover"
This has me a bit lost and confused, any help at all would be appreciated.
Thanks

Here is one option. The only thing that is not very clear is weather if there are two equal values which are also min values or max values they should be removed both or only one max value and one min. I remove just one min and one max value:
int[] arr = new int[] { 2, 2, 3, 4, 5, 6, 6 };
int Lowest = arr[0];
int Highest = arr[0];
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
if (Lowest > arr[i])
{
Lowest = arr[i];
}
if (Highest < arr[i])
{
Highest = arr[i];
}
sum += arr[i];
}
sum -= (Lowest + Highest);
Console.WriteLine("The sum withot the highest and lowest score is : {0}", sum);
and if you and to remove all duplicated min and max scores add this before summing the final score:
int[] arrOfHighest = new int[arr.Length];
int[] arrOfLowest = new int[arr.Length];
int minCounter = 0;
int maxCounter = 0;
for (int i = 0; i < arr.Length; i++)
{
if (Lowest == arr[i])
{
arrOfLowest[minCounter] = arr[i];
minCounter++;
}
if (Highest == arr[i])
{
arrOfHighest[maxCounter] = arr[i];
maxCounter++;
}
}
int sumLoewst = 0;
for (int i = 0; i < arrOfLowest.Length; i++)
{
sumLoewst += arrOfLowest[i];
}
int sumHighest = 0;
for (int i = 0; i < arrOfHighest.Length; i++)
{
sumHighest += arrOfHighest[i];
}
sum -= (sumLoewst + sumHighest);
So the final touch based on the additional information. Since you want the min and max value to be added only once each inthe code above - sum -= (sumLoewst + sumHighest); right after this add:
sum -= (sumLoewst + sumHighest);
sum += (Highest + Lowest);
This way you will have all other values summed, no matter how times they appear in the array. And only one MAX and one MIN value added to the sum.

Related

My code does not check the indexes of all of the arrays (lottery program)

I am making a lottery program, it's basic and only view-able via console at the moment.
The program executes the following:
User enters 6 numbers ranging from 1 - 46.
Program generates 6 random numbers with the same range.
Program compares indexes to see which numbers the user managed to match with the program.
Program displays the same numbers which the user got right.
But, currently, there is a bug in my code and I am not sure how to proceed.
For example, my inputs are: 1 , 2 , 3 , 4 , 5 , 6
The program generated 6 numbers and I've managed to hit number 2 and 6.
But, the program only displayed number 2.
This means that my code is not comparing each and every index, and I am not sure why.
The user array is lucky, and the program generated array is numbers.
Console.WriteLine("The winning numbers are: , " );
int[] winning = new int[6];
int w = 0;
var x = 0;
var j = 0;
Console.WriteLine("The winning numbers are: , " );
int[] winning = new int[6];
int w = 0;
var x = 0;
var j = 0;
while (x< 6)
{
if (lucky[j] == numbers[x])
{
winning[w] = numbers[x];
Console.WriteLine(winning[w]);
w++;
}
j++;
if (j == 5)
{
x++;
j = 0;
}
}
There is no need to do all that looping these days. LINQ's Intersect function makes it a single function call:
var Matches = lucky.Intersect(numbers);
will return all matching numbers from the two lists in Matches.
A looping equivalent might look like this (writing off the top of my head):
List<int> winning = new List<int>();
for(int i=0; i<numbers.Length; i++)
{
if(numbers.Contains(lucky[i])
winning.Add(lucky[i]);
}
To display it on console, use a simple loop:
for(int i=0; i<winning.Length; i++)
{
Console.WriteLine(winning[i]);
}
Since you run over an array, the standard procedure would be to use a for loop.
Here are three solutions that solve the problem.
Each one is complete and can be tested on https://dotnetfiddle.net/
Linq: Use the Intersects method to find the common items between two IEnumerables.
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
List<int> matches = new List<int>(numbers.Intersect(guesses));
foreach (int n in matches)
{
Console.WriteLine("Hit: " + n.ToString());
}
}
}
Using a single for loop and checking with the Contains method (Array implements the IList interface) if the other array contains the number at the current index. You could also use a foreach loop, since you don't care about the indexes.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
List<int> matches = new List<int>();
for (int i = 0; i < guesses.Length; i++)
{
if (numbers.Contains(guesses[i]))
{
Console.WriteLine("Hit: " + guesses[i].ToString());
matches.Add(guesses[i]);
}
}
}
}
Of you could use a nested for loops, one for each array, to check each number from one array against every number of the other one.
Again you could use foreach loops.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
List<int> matches = new List<int>();
for (int i = 0; i < guesses.Length; i++)
{
for (int j = 0; j < numbers.Length; j++)
{
if (guesses[i] == numbers[j])
{
Console.WriteLine("Hit: " + guesses[i].ToString());
matches.Add(guesses[i]);
break; // optional, we found the number and can leave the loop. Not optional if your lottery allows numbers to happen more than once.
}
}
}
}
}
As for the question why your code isn't working:
You set j = 0 when j == 5 just after j++, meaning you set j to 0 after checking index 4. While I do not want to encourage such unorthodox styles you could fix it by comparing j == 6. Again, this approach makes your code unreadable, please use one of the other solutions.
using System;
public class Program
{
public static void Main()
{
// at this point unique numbers have been generated and inputted
int[] numbers = { 1, 2, 3, 4, 5, 6 };
int[] guesses = { 2, 6, 7, 8, 9, 10 };
int[] winning = new int[6];
int w = 0;
var x = 0;
var j = 0;
while (x < 6)
{
if (guesses[j] == numbers[x])
{
winning[w] = numbers[x];
Console.WriteLine(winning[w]);
w++;
}
j++;
if (j == 6)
{
x++;
j = 0;
}
}
}
}
I think what you are looking for is that finding common items from two arrays.
var ar1 = new int[] {1,2,3,4,5,6};
var ar2 = new int[] {2,3,4,6,7,8};
var common = ar1.Intersect(ar2);
In your case
var common = lucky.Intersect(numbers);
Using loops
// Array size is fixed here.
for (int i = 0; i < 6; i++) // OR i < lucky.Length (guessing numbers)
{
if (numbers.Contains(lucky[i]))
{
// NUMBERS DETECTED
}
}
The issue is with the checking of last index(5 in this case). It is never happening!
//say j = 4
lucky[4] == numbers[x] //false/true, whatever value of x is
You increment j
//j is now 5
if(j==5)
Yes and then you are resetting it to 0.
last index which is 5 in this case will never be checked in the next iteration
Solution-
if(j == 6)
I ended up building 2 methods that basically do what everyone here has told me.
Since I did not yet learn LinQ I couldn't understand , I didn't learn LIST as well so I couldn't use it as well.
My functions are like this:
First function: checks the indexes of a specified array
code:
static bool DoesExists(int[] a, int Value)
{
for (int i = 0; i < a.Length; i++)
{
if (Value == a[i])
{
return true;
}
}
return false;
}
second function checks how many repeated elements are in 2 arrays
code:
static int CountCorrect(int[] pc, int[] user)
{
int count = 0;
for (int i = 0; i < user.Length; i++)
{
if (DoesExists(pc, user[i]))
{
count++;
}
}
return count;
}
when using these 2 in conjunction , it solves my problem.
thanks to everyone for taking the time to give me good ideas.

In my class i have to creating a method to find multiple maximum numbers in an array C#

In my class i have to create a method that will find multiple maximum numbers within an array. the user will input how many maximum numbers they are wanting and then the code should display all those numbers. if i select 2 this code will show me the 2 maximum numbers but if im wanting more it just doesnt work. i was trying to search the array for the maximum number and then have it display the outcome and then change that element to 0 and than repeat the loop until it hits that number (userinput). im soo frustrated can someone help me please
public static int FindingMaxNum(int[] arr, int max)
{
int userinput;
Console.Write("Enter the number of maximum values: ");
userinput = Convert.ToInt32(Console.Read());
int i = 0;
int c = 0;
for (i = 0; i < arr.Length; i++)
{
if (arr[i] >= max)
{
max = arr[i];
c++;
while (c <= userinput)
{
Console.WriteLine(max);
arr[i] = 0;
break;
}
}
}
return -1;
}
If I understand correctly, you want to get some number of items from an array whose values are greater than all the others in the array.
If so, something like this modified version of your method may do the trick:
public static void WriteMaxNum(int[] arr)
{
if (arr == null)
{
Console.WriteLine("The array is null");
return;
}
if (arr.Length == 0)
{
Console.WriteLine("The array is empty");
return;
}
int count = arr.Length;
int numMaxValues;
// Get number of max values to return from user
do
{
Console.Write("Enter the number of maximum values (1 - {0}): ", count);
} while (!int.TryParse(Console.ReadLine(), out numMaxValues) ||
numMaxValues < 1 ||
numMaxValues > count);
// Output the max values
Console.Write("The {0} max values are: ", numMaxValues);
Console.WriteLine(string.Join(", ", arr.OrderByDescending(i => i).Take(numMaxValues)));
}
Usage
static void Main(string[] args)
{
var myArray = new[] { 1, 9, 4, 8, 2, 5, 0, 7, 6, 3 };
WriteMaxNum(myArray);
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();
}
Output
Simple solution with average complexity O(nlogn):
Sort the array first then print the last N nos.
int[] arr = new int[]{-5,-69,1250,24,-96,32578,11,124};
Array.Sort(arr);
int n=3;
for(int i=arr.Length-1;i>=0 && n>0 ;--i){
n--;
Console.WriteLine(arr[i]);
}
Now coming to your code, there are multiple problems. First there is no need to take 'max' as parameter in your function. Second you are looping only arr.Length times once. There should be nested loop, outer one of which has to run userInput times and inner on has to iterate over all the values. Third you should initialize to extracted value position to minimum value so that the method works for negative numbers too.
Refined code:
for(int i=0;i<userinput;++i){
int max = int.MinValue,pos=-1;
for(int j=0;j<arr.Length;++j){
if(max<arr[j]){
pos = j;
max = arr[j];
}
}
arr[pos] = int.MinValue;
Console.Write(max+",");
}

The biggest value in array and check if all elements in array have equal values. (C#)

I'm working on a project. The user inputs a value(n) and that value is multiplied by 2. Then the user inputs the exact same times a new number (n*2). So I have to figure out if every couple of numbers are equal and if not to print the biggest difference between one of the couples. In order to do that I need Biggest value in an array and somehow to check if all elements in an array are equal. I'm new to C# and I don't know much about arrays.(btw sorry about the use of language, I'm foreigner)
I came up with this code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EqualPairs
{
class Program
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
int sum = 0;
int diff = 0;
int[] sumAll = new int[n];
int[] differ = new int[n];
for (int i = 1; i <= n; i++)
{
sum = 0;
diff = 0;
for (int j = 1; j <= 2; j++)
{
int number = int.Parse(Console.ReadLine());
sum = sum + number;
diff = Math.Abs(diff - number);
}
sumAll[i - 1] = sum;
differ[i - 1] = diff;
}
}
}
}
I'm not sure exactly what you're trying to do with your program, but to answer your questions:
Find max value in an array:
int maxValue = yourArray.Max();
Check if all values in your array are equal (using System.Linq):
int first = yourArray.First();
bool allElementsEqual = yourArray.All(x => x == first);
Edit based on OP's comment:
If I were you, I'd create an intermediate array couplesArray. Not sure how you're planning to set up your inputs and all that, but I'm assuming yourArray has an even number of values. I don't know how you're defining max difference and all that, so perhaps drop some of my Math.Abs() calls:
int[] yourArray = { 1, 2, 0, 3, 4, -1};
int[] couplesArray = new int[yourArray.Count() / 2];
for (int i = 0; i < couplesArray.Length; i++)
{
couplesArray[i] = yourArray[2 * i] + yourArray[2 * i + 1];
}
int first = couplesArray.First();
bool allElementsEqual = couplesArray.All(x => x == first);
int maxDifference = Math.Max(Math.Abs(couplesArray.Max()), Math.Abs(couplesArray.Min()));
string outputString = allElementsEqual ? "Equal" : maxDifference.ToString();
Console.WriteLine(outputString);

Function to multiply array elements

im doing a calculator, this is the code:
If i go to the Multiplication function and i enter for example i want to multiple 2*2*2
this code it's outputting 4 8 4
I dont understand why, well i know that 2*2 = 4 * 2 = 8 but why the last 4?
and how can i only get the result without getting the complete series?, when i try to do the Console WriteLine outside the for loops it throws an error. it doesn't let me.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void LetsSum(int [] myArray)
{
int sum = myArray.Sum();
Console.WriteLine(sum);
}
static void letsMult(int [] myArray)
{
for (int a = 0; a < myArray.Length; a++ )
{
for (int b = a+1; b < myArray.Length; b++ )
{
int multip = myArray[a] *= myArray[b];
Console.WriteLine(multip);
}
}
}
static void Main(string[] args)
{
//First Variable total of numbers from users input
int TotalNumb = 0;
//String to receive users input
string TotalN = string.Empty;
//Specifying size of array
Console.WriteLine("Please specify how many numbers do you want to do the math");
TotalN = Console.ReadLine();
//Converte because readline it's a string
TotalNumb = Convert.ToInt32(TotalN);
//Name of ARRAY and passing the value selected by the user
int[] myArray = new int[TotalNumb];
//counter for the loop
int i = 0;
for (i = 0; i < TotalNumb; i++ )
{
Console.WriteLine("Enter your number");
myArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.WriteLine("Please enter SUM, LESS, MULT, DIV");
string ToDo = Console.ReadLine();
if (ToDo == "SUM")
{
Program.LetsSum(myArray);
}
if (ToDo == "MULT")
{
Program.letsMult(myArray);
}
Console.Read();
}
}
}
Very simple... alter your code like as bellow...
static void letsMult(int [] myArray)
{
int output=1;
for (int a = 0; a < myArray.Length; a++ )
{
output=output*myArray[a];
Console.WriteLine(output);
}
}
The error message is because you're declaring int multip in the innermost scope of the for loop. The int goes out of scope after that, and is not usable. If you want multip to be accessible outside of the for loop, declare it outside of the for loop:
static void letsMult(int [] myArray)
{
int multip = 1;
for (int a = 0; a < myArray.Length; a++ )
{
for (int b = a+1; b < myArray.Length; b++ )
{
multip = myArray[a] *= myArray[b];
}
}
Console.WriteLine(multip);
}
Note, it's declared above the for loop, but used in the loop, and outputted outside the loop, but still in its scope (which in my case is "the entire function").
You still have a logical issue. Are you sure you need a nested loop? How would you describe to a person how to multiply a list of numbers to get the total product?
You have 3 Elements in your Array
[2, 2, 2]
Then you multiply 0 and 1 and output the result:
[4, 2, 2] OUTPUT: 4
Then you multiply 0 and 2 and output the result:
[8, 2, 2] OUTPUT: 8
The n you multiply 1 and 2 and output the result:
[8, 4, 2] OUTPUT: 8
Perhaps you want to remove the outer loop, in this case your Output would be
4, 8
You can do this with LINQ's Aggregate():
for sum :
int[] arr1 = new int[] { 2, 2, 2 };
int result = arr1.Aggregate((a, b) => b + a);
//or
int result = arr1.Sum();
for multiplication :
int[] arr1 = new int[] { 2, 2, 2 };
int result = arr1.Aggregate((a, b) => b * a);
I guess you want to display each multiplacation result.If so you can do the following:
int multip = myArray[0];
for (int a = 1; a < myArray.Length; a++ )
{
Console.Write("{0} * {1} = ",multip, myArray[a]);
multip *= myArray[a];
Console.WriteLine(multip);
}
use
int multip=1;
for (int a = 0; a < myArray.Length; a++ )
{
multip *= myArray[a];
Console.WriteLine(multip);
}
}

Given an array of integers. Find the LARGEST subarray with the MAXIMUM sum

Hi I am preparing for an interview code test and I stumbled across this question. I tried attempting it in C#, below is my embarrasing answer which I don't even know if it's right but mostly I guess not, could someone please kindly provide me with the answer so that when I rework on the solution I can at least have the answer to verify the output. Thanks.
Sample data:
int[] arr = {5, 1, -7, 3, 7};
Code:
int[] LargestsubarrayMaxSum(int[] arr)
{
int temp = 0;
int[] resultArr = new int[arr.Length];
for (int i = 0; i < arr.Length - 1; i++)
{
if (i != 0)
{
foreach (int item in resultArr)
{
temp += item;
}
if (temp + arr[i + 1] > 0)
{
resultArr[i + 1] = temp + arr[i + 1];
}
}
else
{
if ((arr[i] + arr[i + 1]) >= 0)
{
resultArr[i] = arr[i];
resultArr[i + 1] = arr[i] + arr[i + 1];
}
else
{
resultArr[i] = arr[i];
resultArr[i + 1] = 0;
}
}
}
return resultArr;
}
How about this?
var arr = new [] {5, 1, -7, 3, 7};
var xs =
from n in Enumerable.Range(0, arr.Length)
from l in Enumerable.Range(1, arr.Length - n)
let subseq = arr.Skip(n).Take(l)
orderby subseq.Count() descending
orderby subseq.Sum() descending
select subseq;
var maxSumSubseq = xs.First();
EDIT: Added orderby subseq.Count() descending to get maximal length subsequence.
EDIT: Added explanation as per comment.
Select all possible subsequence starting indices:
from n in Enumerable.Range(0, arr.Length)
Select all possible lengths of subsequences given the starting index:
from l in Enumerable.Range(1, arr.Length - n)
Extract the subsequence from the array:
let subseq = arr.Skip(n).Take(l)
Order subsequences by descending length (i.e. longest first) - could order by l instead of subseq.Count() but the latter is more expressive even though the former is more efficient:
orderby subseq.Count() descending
Calculate the sum of each subsequence and order the subsequences so highest valued sums are first:
orderby subseq.Sum() descending
Select the subsequences:
select subseq;
Only select the first subsequence - it's the highest value sum with the greatest length:
xs.First();
Hope this helps.
O(N) time complexity and O(1) space complexity. This is the optimal solution I know:
#include <stdio.h>
#include <limits.h>
int get_max_sum(int* array, int len, int* start, int* end)
{
int max_sum = INT_MIN, sum = 0, i;
int tmp_start = 0;
for(i = 0; i != len; ++i)
{
sum += array[i];
// if the sum is equal, choose the one with more elements
if(sum > max_sum || (sum == max_sum && (end - start) < (i - tmp_start)))
{
max_sum = sum;
*start = tmp_start;
*end = i;
}
if(sum < 0)
{
sum = 0;
tmp_start = i + 1;
}
}
return max_sum;
}
Here are some test cases:
int main(int argc, char **argv)
{
int arr1[] = {5, 1, -7, 3, 7};
int arr2[] = {1};
int arr3[] = {-1, -7, -3, -7};
int arr4[] = {5, 1, -7, 2, 2, 2};
int start, end, sum;
sum = get_max_sum(arr1, 5, &start, &end);
printf("sum: %d, start: %d, end: %d\n", sum, start, end);
sum = get_max_sum(arr2, 1, &start, &end);
printf("sum: %d, start: %d, end: %d\n", sum, start, end);
sum = get_max_sum(arr3, 4, &start, &end);
printf("sum: %d, start: %d, end: %d\n", sum, start, end);
sum = get_max_sum(arr4, 6, &start, &end);
printf("sum: %d, start: %d, end: %d\n", sum, start, end);
return 0;
}
$ ./a.out
sum: 10, start: 3, end: 4
sum: 1, start: 0, end: 0
sum: -1, start: 0, end: 0
sum: 6, start: 3, end: 5
Update1:
Added code to print the index of the subarray.
Update2:
If two sub arrays with the same sum are found, choose the one with more elements.
Update3:
Fix the algorithm for leading negative numbers
You could either use Enigmativity's answer but add the extra order by of subseq.Count() descending
or if you want an insane linq query......
int[] arr = .......
var result = new[]{0}
.Concat(arr.Select((x,i)=>new {x,i})
.Where(a=>a.x<0).Select(a=>a.i+1))
.Select (i => arr.Skip(i).TakeWhile(a => a>=0))
.OrderByDescending(a=>a.Sum())
.OrderByDescending(a=>a.Count()).First();
However usually you want to do these as a single loop..
var result=new List<int>();
var maxResult=new List<int>();
// These next four variables could be calculated on the fly
// but this way prevents reiterating the list each loop.
var count=0;
var sum=0;
var maxCount=0;
var maxSum=0;
foreach (var value in arr) {
if (value >=0) {
result.Add(value);
sum+=value;
count++;
} else {
if (sum>maxSum || (sum==maxSum && count>maxCount)) {
maxSum=sum;
maxCount=count;
maxResult=result;
}
result.Clear();
count=0;
sum=0;
}
}
var returnValue=maxResult.ToArray();
public static int[] FindMaxArrayEx(int[] srcArray)
{
int[] maxArray = new int[1];
int maxTotal = int.MinValue;
int curIndex = 0;
int tmpTotal = 0;
List<int> tmpArray = new List<int>();
if (srcArray.Length != 1)
{
for (int i = 0; i < srcArray.Length; i++)
{
tmpTotal = 0;
curIndex = i;
tmpArray.Clear();
while (curIndex < srcArray.Length)
{
tmpTotal += srcArray[curIndex];
tmpArray.Add(srcArray[curIndex]);
if (tmpTotal > maxTotal)
{
maxTotal = tmpTotal;
maxArray = tmpArray.ToArray();
}
curIndex++;
}
}
}
else
{
maxTotal = srcArray[0];
maxArray = srcArray;
}
Console.WriteLine("FindMaxArrayEx: {0}",maxTotal);
return maxArray;
}
Here is a totally working solution:
using System;
using System.Collections.Generic;
class MaxSumOfSubArray
{
static void Main()
{
//int[] array = { 2, 3, -6, -1, 2, -1, 6, 4, -8, 8 };
//maxSubSum(array);
int digits;
List<int> array = new List<int>();
Console.WriteLine("Please enter array of integer values. To exit, enter eny key different than 0..9");
while (int.TryParse(Console.ReadLine(), out digits))
{
array.Add(digits);
}
maxSubSum(array);
}
public static void maxSubSum(List<int> arr)
{
int maxSum = 0;
int currentSum = 0;
int i = 0;
int j = 0;
int seqStart=0;
int seqEnd=0;
while (j < arr.Count)
{
currentSum = currentSum + arr[j];
if (currentSum > maxSum)
{
maxSum = currentSum;
seqStart = i;
seqEnd = j;
}
else if (currentSum < 0)
{
i = j + 1;
currentSum = 0;
}
j++;
}
Console.Write("The sequence of maximal sum in given array is: {");
for (int seq = seqStart; seq <= seqEnd; seq++)
{
Console.Write(arr[seq] + " ");
}
Console.WriteLine("\b}");
Console.WriteLine("The maximum sum of subarray is: {0}", maxSum);
}
}
/// <summary>
/// given an non-empty input array of integers, this method returns the largest contiguous sum
/// </summary>
/// <param name="inputArray">the non-empty input array of integeres</param>
/// <returns>int, the largest contiguous sum</returns>
/// <remarks>time complexity O(n)</remarks>
static int GetLargestContiguousSum(int[] inputArray)
{
//find length of the string, if empty throw an exception
if (inputArray.Length == 0)
throw new ArgumentException("the input parameter cannot be an empty array");
int maxSum = 0;
int currentSum = 0;
maxSum = currentSum = inputArray[0];
for (int i = 1; i < inputArray.Length; i++) //skip i=0 as currentSum=inputArray[0].
{
currentSum = Math.Max(currentSum + inputArray[i], inputArray[i]);
maxSum = Math.Max(currentSum, maxSum);
}
return maxSum;
}
/*--This was the algorithum I found on Wiki to calculate sum, however to get the actual subarray
* I really had to think. After spending few hours I was able to solve it using startIndex and
* endIndex int variables and then by adding a if clause if (max_ending_here == array[i])
{ startIndex = i; }
* dang this was very tough. I hope you all will refactor as needed to make some improvements.*/
/* Initialize:
max_so_far = 0
max_ending_here = 0
Loop for each element of the array
(a) max_ending_here = max_ending_here + a[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
int[] array = { -2, 1, -3, 4, -1, 2, 1, -5, 4 };
int[] largestSubArray;
largestSubArray = Max_Array(array);
Console.WriteLine();
Console.WriteLine("Subarray is :");
foreach (int numb in largestSubArray)
Console.WriteLine(numb);
Console.ReadKey();
}
//Max_Array function will calculate the largest contigent array
//sum and then find out startIndex and endIndex of sub array
//within for loop.Using this startIndex and endIndex new subarray
//is created with the name of largestSubArray and values are copied
//from original array.
public static int[] Max_Array(int[] array)
{
int[] largestSubArray;
int max_so_far = 0, max_ending_here = 0, startIndex = 0,
endIndex = 0;
for (int i = 0, j = 0; i < array.Length; i++)
{
max_ending_here += array[i];
if (max_ending_here <= 0)
{
max_ending_here = 0;
}
if (max_ending_here == array[i])
{ startIndex = i; }
if (max_so_far < max_ending_here)
{
max_so_far = max_ending_here;
endIndex = i;
}
}
Console.WriteLine("Largest sum is: {0}", max_so_far);
largestSubArray = new int[(endIndex - startIndex) + 1];
Array.Copy(array, startIndex, largestSubArray, 0, (endIndex - startIndex) + 1);
return largestSubArray;
}
}
}
Output
Largest sum is: 6
'Subarray is:
4,
-1,
2,
1'
It's not that complicated once you go over it. I thought about it going backwards at first, that helped for some reason.
If all numbers are positive (or 0), the entire array would be the largest subarray with max sum.
Now, we can take this fact and apply it over positive or negative arrays and instead say that we want to include all subarrays that are positive (or 0).
Start at the end and sum as you go left. When you find a negative number, you think, did that negative number make the rest of my sums worthless? if not, you keep going.. but you also mark that point right there as the current max sum (if it's greater than the last current max sum).
If they are worthless, (ie sum is now less than 0), you know that everything to the right of your index is now worthless. You still keep your current max sum in case thats the highest though.
start from 3 with your new index. Keep track of the indexes for your current max sum and end.
The SubArray with Maximum Sum in an Array is the Array without the Minimum most element element. So sort it. and remove the minimum element. thats it.
Thats applicable if Its Only Positive Integer Array. Otherwise the subarray of Positive elements only is the answer
below code working for me :
static void Main(string[] args)
{
string str = Console.ReadLine();
int [] arr = Array.ConvertAll(str.Split(' '),int.Parse);
int curSum = 0, maxSum = 0;
curSum = maxSum = arr[0];
for (int i = 1; i < arr.Length; i++)
{
curSum = Math.Max(curSum + arr[i], arr[i]);
maxSum = Math.Max(curSum, maxSum);
}
Console.WriteLine("{0}", maxSum);
Console.ReadKey();
}
Input : -2 1 -3 4 -1 2 1 -5 4
O/P: 6

Categories

Resources