i need to organize the numbers and get the median and mode from any quantity of numbers, so i tried different ways to implement this but i just can't get with the solution.
public static void Main()
{
int i, n;
int[] a = new int[100];
Console.Write("\n\nRead n number of values in an array and display it in reverse order:\n");
Console.Write("------------------------------------------------------------------------\n");
Console.Write("Input the number of elements to store in the array :");
n = Convert.ToInt32(Console.ReadLine());
//quantity of numbers to insert
Console.Write("Input {0} number of elements in the array :\n", n);
for (i = 0; i < n; i++)
{
Console.Write("element - {0} : ", i);
a[i] = Convert.ToInt32(Console.ReadLine());
}
//individial numbers to insert
Console.Write("\nThe values store into the array are : \n");
for (i = 0; i < n; i++)
{
Console.Write("{0} ", a[i]);
}
}
i tried to use this, but i don't know how to use it
public static class Extensions
{
public static decimal GetMedian(this int[] array)
{
int[] tempArray = array;
int count = tempArray.Length;
Array.Sort(tempArray);
decimal medianValue = 0;
if (count % 2 == 0)
{
// count is even, need to get the middle two elements, add them together, then divide by 2
int middleElement1 = tempArray[(count / 2) - 1];
int middleElement2 = tempArray[(count / 2)];
medianValue = (middleElement1 + middleElement2) / 2;
}
else
{
// count is odd, simply get the middle element.
medianValue = tempArray[(count / 2)];
}
return medianValue;
}
}
Median is a middle item (or average of two middle items) in the sorted collection:
using System.Linq;
...
int[] a = ...
...
double median = a
.OrderBy(item => item) // from sorted sequence
.Skip((a.Length - 1) / 2) // we skip leading half items
.Take(2 - a.Length % 2) // take one or two middle items
.Average(); // get average of them
Mode is the local maximum of the distribution, the most frequent element in it:
int mode = a
.GroupBy(item => item)
.OrderByDescending(group => group.Count())
.First().Key;
I got asked a question and now I am kicking myself for not being able to come up with the exact/correct result.
Imagine we have a function that splits a string into multiple lines but each line has to have x number of characters before we "split" to the new line:
private string[] GetPagedMessages(string input, int maxCharsPerLine) { ... }
For each line, we need to incorporate, at the end of the line "x/y" which is basically 1/4, 2/4 etc...
Now, the paging mechanism must also be part of the length restriction per line.
I have been overworked and overthinking and tripping up on things and this seems pretty straight forward but for the life of me, I cannot figure it out! What am I not "getting"?
What am I interested in? The calculation and some part of the logic but mainly the calculation of how many lines are required to split the input based on the max chars per line which also needs to include the x/y.
Remember: we can have more than a single digit for the x/y (i.e: not just 1/4 but also 10/17 or 99/200)
Samples:
input = "This is a long message"
maxCharsPerLine = 10
output:
This i 1/4 // << Max 10 chars
s a lo 2/4 // << Max 10 chars
ng mes 3/4 // << Max 10 chars
sage 4/4 // << Max 10 chars
Overall the logic is simple but its just the calculation that is throwing me off.
The idea: First, find how many digits is the number of lines:
(n = input.Length, maxCharsPerLine = 10)
if n <= 9*(10-4) ==> 1 digit
if n <= 9*(10-5) + 90*(10-6) ==> 2 digits
if n <= 9*(10-6) + 90*(10-7) + 900*(10-8) ==> 3 digits
if n <= 9*(10-7) + 90*(10-8) + 900*(10-9) + 9000*(10-10) ==> No solution
Then, subtract the spare number of lines. The solution:
private static int GetNumberOfLines(string input, int maxCharsPerLine)
{
int n = input.Length;
int x = maxCharsPerLine;
for (int i = 4; i < x; i++)
{
int j, sum = 0, d = 9, numberOfLines = 0;
for (j = i; j <= i + i - 4; j++)
{
if (x - j <= 0)
return -1; // No solution
sum += d * (x - j);
numberOfLines += d;
d *= 10;
}
if (n <= sum)
return numberOfLines - (sum - n) / (x - j + 1);
}
return -2; // Invalid
}
Usage:
private static string[] GetPagedMessages(string input, int maxCharsPerLine)
{
int numberOfLines = GetNumberOfLines(input, maxCharsPerLine);
if (numberOfLines < 0)
return null;
string[] result = new string[numberOfLines];
int spaceLeftForLine = maxCharsPerLine - numberOfLines.ToString().Length - 2; // Remove the chars of " x/y" except the incremental 'x'
int inputPosition = 0;
for (int line = 1; line < numberOfLines; line++)
{
int charsInLine = spaceLeftForLine - line.ToString().Length;
result[line - 1] = input.Substring(inputPosition, charsInLine) + $" {line}/{numberOfLines}";
inputPosition += charsInLine;
}
result[numberOfLines-1] = input.Substring(inputPosition) + $" {numberOfLines}/{numberOfLines}";
return result;
}
A naive approach is to start counting the line lengths minus the "pager"'s size, until the line count changes in size ("1/9" is shorter than "1/10", which is shorter than "11/20", and so on):
private static int[] GetLineLengths(string input, int maxCharsPerLine)
{
/* The "pager" (x/y) is at least 4 characters (including the preceding space) and at most ... 8?
* 7/9 (4)
* 1/10 (5)
* 42/69 (6)
* 3/123 (6)
* 42/420 (7)
* 999/999 (8)
*/
int charsRemaining = input.Length;
var lineLengths = new List<int>();
// Start with " 1/2", (1 + 1 + 2) = 4 length
var highestLineNumberLength = 1;
var lineNumber = 0;
do
{
lineNumber++;
var currentLineNumberLength = lineNumber.ToString().Length; // 1 = 1, 99 = 2, ...
if (currentLineNumberLength > highestLineNumberLength)
{
// Pager size changed, reset
highestLineNumberLength = currentLineNumberLength;
lineLengths.Clear();
lineNumber = 0;
charsRemaining = input.Length;
continue;
}
var pagerSize = currentLineNumberLength + highestLineNumberLength + 2;
var lineLength = maxCharsPerLine - pagerSize;
if (lineLength <= 0)
{
throw new ArgumentException($"Can't split input of size {input.Length} into chunks of size {maxCharsPerLine}");
}
lineLengths.Add(lineLength);
charsRemaining -= lineLength;
}
while (charsRemaining > 0);
return lineLengths.ToArray();
}
Usage:
private static string[] GetPagedMessages(string input, int maxCharsPerLine)
{
if (input.Length <= maxCharsPerLine)
{
// Assumption: no pager required for a message that takes one line
return new[] { input };
}
var lineLengths = GetLineLengths(input, maxCharsPerLine);
var result = new string[lineLengths.Length];
// Cut the input and append the pager
var previousIndex = 0;
for (var i = 0; i < lineLengths.Length; i++)
{
var lineLength = Math.Min(lineLengths[i], input.Length - previousIndex); // To cater for final line being shorter
result[i] = input.Substring(previousIndex, lineLength) + " " + (i + 1) + "/" + lineLengths.Length;
previousIndex += lineLength;
}
return result;
}
Prints, for example:
This 1/20
is a 2/20
long 3/20
strin 4/20
g tha 5/20
t wil 6/20
l spa 7/20
n mor 8/20
e tha 9/20
n te 10/20
n li 11/20
nes 12/20
beca 13/20
use 14/20
of i 15/20
ts e 16/20
norm 17/20
ous 18/20
leng 19/20
th 20/20
I have an array of string elements of various words. I need the characters of each word be split equally into the text component of 3 buttons. For example, the array could hold the elements "maybe", "his", "car". In each game one of these words will be pulled from the array and its characters divided into the 3 buttons. For example, button 1 will have "ma", button 2 will have "yb" and button 3 "e" (for the word maybe). I then hide the text element of one button for the user to drag and drop the correct missing letter(s) into the space. The purpose of the game is to help children learn to spell. Does anyone know how I could go about dividing the characters equally into the 3 buttons?
Here's a function that would split the word into the amount of segments you want. You can then iterate over that list to set each segment to a button.Text.
public List<string> SplitInSegments(string word, int segments)
{
int wordLength = word.Length;
// The remainder tells us how many segments will get an extra letter
int remainder = wordLength % segments;
// The base length of a segment
// This is a floor division, because we're dividing ints.
// So 5 / 3 = 1
int segmentLength = wordLength / segments;
var result = new List<string>();
int startIndex = 0;
for (int i = 0; i < segments; i++)
{
// This segment may get an extra letter, if its index is smaller then the remainder
int currentSegmentLength = segmentLength + (i < remainder ? 1 : 0);
string currentSegment = word.Substring(startIndex, currentSegmentLength);
// Set the startindex for the next segment.
startIndex += currentSegmentLength;
result.Add(currentSegment);
}
return result;
}
usage:
// returns ["ma", "yb", "e"]
var segments = SplitInSegments("maybe", 3);
Edit
I like the fact that this is for teaching children. So here comes.
Regarding your question on splitting the string based on specific letter sequences: After you've split the string using regex, you will have an array of strings. Then determine the amount of items in the splitted string and concatenate or split further based on the number of segments:
// sequences to split on first
static readonly string[] splitSequences = {
"el",
"ol",
"bo"
};
static readonly string regexDelimiters = string.Join('|', splitSequences.Select(s => "(" + s + ")"));
// Method to split on sequences
public static List<string> SplitOnSequences(string word)
{
return Regex.Split(word, regexDelimiters).Where(s => !string.IsNullOrEmpty(s)).ToList();
}
public static List<string> SplitInSegments(string word, int segments)
{
int wordLength = word.Length;
// The remainder tells us how many segments will get an extra letter
int remainder = wordLength % segments;
// The base length of a segment
// This is a floor division, because we're dividing ints.
// So 5 / 3 = 1
int segmentLength = wordLength / segments;
var result = new List<string>();
int startIndex = 0;
for (int i = 0; i < segments; i++)
{
// This segment may get an extra letter, if its index is smaller then the remainder
int currentSegmentLength = segmentLength + (i < remainder ? 1 : 0);
string currentSegment = word.Substring(startIndex, currentSegmentLength);
// Set the startindex for the next segment.
startIndex += currentSegmentLength;
result.Add(currentSegment);
}
return result;
}
// Splitword will now always return 3 segments
public static List<string> SplitWord(string word)
{
if (word == null)
{
throw new ArgumentNullException(nameof(word));
}
if (word.Length < 3)
{
throw new ArgumentException("Word must be at least 3 characters long", nameof(word));
}
var splitted = SplitOnSequences(word);
var result = new List<string>();
if (splitted.Count == 1)
{
// If the result is not splitted, just split it evenly.
result = SplitInSegments(word, 3);
}
else if (splitted.Count == 2)
{
// If we've got 2 segments, split the shortest segment again.
if (splitted[1].Length > splitted[0].Length
&& !splitSequences.Contains(splitted[1]))
{
result.Add(splitted[0]);
result.AddRange(SplitInSegments(splitted[1], 2));
}
else
{
result.AddRange(SplitInSegments(splitted[0], 2));
result.Add(splitted[1]);
}
}
else // splitted.Count >= 3
{
// 3 segments is good.
result = splitted;
// More than 3 segments, combine some together.
while (result.Count > 3)
{
// Find the shortest combination of two segments
int shortestComboCount = int.MaxValue;
int shortestComboIndex = 0;
for (int i = 0; i < result.Count - 1; i++)
{
int currentComboCount = result[i].Length + result[i + 1].Length;
if (currentComboCount < shortestComboCount)
{
shortestComboCount = currentComboCount;
shortestComboIndex = i;
}
}
// Combine the shortest segments and replace in the result.
string combo = result[shortestComboIndex] + result[shortestComboIndex + 1];
result.RemoveAt(shortestComboIndex + 1);
result[shortestComboIndex] = combo;
}
}
return result;
}
Now when you call the code:
// always returns three segments.
var splitted = SplitWord(word);
Here is another approach.
First make sure that the word can be divided by the desired segments (add a dummy space if necessary) , then use a Linq statement to get your parts and when adding the result trim away the dummy characters.
public static string[] SplitInSegments(string word, int segments)
{
while(word.Length % segments != 0) { word+=" ";}
var result = new List<string>();
for(int x=0; x < word.Count(); x += word.Length / segments)
result.Add((new string(word.Skip(x).Take(word.Length / segments).ToArray()).Trim()));
return result.ToArray();
}
You can split your string into a list and generate buttons based on your list. The logic for splitting the word into a string list would be something similar to this:
string test = "maybe";
List list = new List();
int i = 0, len = 2;
while(i <= test.Length)
{
int lastIndex = test.Length - 1;
list.Add(test.Substring(i, i + len > lastIndex? (i + len) - test.Length : len));
i += len;
}
HTH
I want to make a method that takes a variable of type int or long and returns an array of ints or longs, with each array item being a group of 3 digits. For example:
int[] i = splitNumber(100000);
// Outputs { 100, 000 }
int[] j = splitNumber(12345);
// Outputs { 12, 345 }
int[] k = splitNumber(12345678);
// Outputs { 12, 345, 678 }
// Et cetera
I know how to get the last n digits of a number using the modulo operator, but I have no idea how to get the first n digits, which is the only way to make this method that I can think of. Help please!
Without converting to string:
int[] splitNumber(int value)
{
Stack<int> q = new Stack<int>();
do
{
q.Push(value%1000);
value /= 1000;
} while (value>0);
return q.ToArray();
}
This is simple integer arithmetic; first take the modulo to get the right-most decimals, then divide to throw away the decimals you already added. I used the Stack to avoid reversing a list.
Edit: Using log to get the length was suggested in the comments. It could make for slightly shorter code, but in my opinion it is not better code, because the intent is less clear when reading it. Also, it might be less performant due to the extra Math function calls. Anyways; here it is:
int[] splitNumber(int value)
{
int length = (int) (1 + Math.Log(value, 1000));
var result = from n in Enumerable.Range(1,length)
select ((int)(value / Math.Pow(1000,length-n))) % 1000;
return result.ToArray();
}
By converting into a string and then into int array
int number = 1000000;
string parts = number.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
By using Maths,
public static int[] splitNumberIntoGroupOfDigits(int number)
{
var numberOfDigits = Math.Floor(Math.Log10(number) + 1); // compute number of digits
var intArray = new int[Convert.ToInt32(numberOfDigits / 3)]; // we know the size of array
var lastIndex = intArray.Length -1; // start filling array from the end
while (number != 0)
{
var lastSet = number % 1000;
number = number / 1000;
if (lastSet == 0)
{
intArray[lastIndex] = 0; // set of zeros
--lastIndex;
}
else if (number == 0)
{
intArray[lastIndex] = lastSet; // this could be your last set
--lastIndex;
}
else
{
intArray[lastIndex] = lastSet;
--lastIndex;
}
}
return intArray;
}
Try converting it to string first and do the parsing then convert it back to number again
Convert to string
Get length
If length modulus 3 == 0
String substring it into ints every 3
else if
Find remainder such as one or two left over
Substring remainder off of front of string
Then substring by 3 for the rest
You can first find out how large the number is, then use division to get the first digits, and modulo to keep the rest:
int number = 12345678;
int len = 1;
int div = 1;
while (number >= div * 1000) {
len++;
div *= 1000;
}
int[] result = new int[len];
for (int i = 0; i < result.Length; i++) {
result[i] = number / div;
number %= div;
div /= 1000;
}
You can use this with the System.Linq namespace from .NET 3.5 and above:
int[] splitNumber(long value)
{
LinkedList<int> results = new LinkedList<int>();
do
{
int current = (int) (value % 1000);
results.AddFirst(current);
value /= 1000;
} while (value > 0);
return results.ToArray();// Extension method
}
I use LinkedList<int> to avoid having to Reverse a list before returning. You could also use Stack<int> for the same purpose, which would only require .NET 2.0:
int[] splitNumber(long value)
{
Stack<int> results = new Stack<int>();
do
{
int current = (int) (value % 1000);
results.Push(current);
value /= 1000;
} while (value > 0);
return results.ToArray();
}
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