My program is supposed to take a provided array and create a new array where each element is the sum of the previous elements in original array. For example element one in new array is element one in original array. Element two in new array is sum of element one an element two in original array. Element three in new array is sum of elements one, two and three in original array. I wrote this but I know it is incomplete. Please guide.
public class PrefixSum
{
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int x = 0;
for(int i = 0; i < array.length; i++)
{
x = array[i];
x = x + i;
}
newArray[0] = 0;
System.out.println(" " + newArray[x]);
}
}
You can use a variable runningTotal to keep count of the running total like so:
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int[] originalArray = new int[]{0,5,1,-3,2,0,4};
int[] sumArray = new int[originalArray.length];
int runningTotal = 0;
for(int i = 0; i < originalArray.length; i++){
runningTotal += originalArray[i];
sumArray[i] = runningTotal;
}
System.out.println("The originalArray is: " + Arrays.toString(originalArray));
System.out.println("The sumArray is: " + Arrays.toString(sumArray));
}
}
Output:
The originalArray is: [0, 5, 1, -3, 2, 0, 4]
The sumArray is: [0, 5, 6, 3, 5, 5, 9]
Try it here!
You may Debug this code in order to understand the changes.
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int x = 0;
for(int i = 0; i < array.length; i++)
{
x += array[i];
newArray[i] = x;
}
}
public static void main(String[] args)
{
int[] array = new int[]{0,5,1,-3,2,0,4};
int[] newArray = new int[7];
int sum = 0;
for(int i = 0; i < array.length; i++)
{
sum += array[i];
newArray[i]= sum;
System.out.println(" " +newArray[i]);
}
}
List<Integer> sums = new ArrayList<>();
Stream.of(0, 5, 1, -3, 2, 0, 4).reduce((left, right) -> {
sums.add(left + right);
return left + right;
});
Printing sums after running yields :
[0, 5, 6, 3, 5, 5, 9]
Try it here.
Related
I am learning Java and wanted to find the contiguous sub-array with maximum sum. I am able to find it, but when I am going outside the for loop, the value of the sub-array saved in an ArrayList changes.
public class FindingSumOfContiguousSubArray {
//code for computing sum of an array list
public int getSum (ArrayList <Integer> arraylist ) {
int sum = 0;
for (int i=0; i<arraylist.size(); i++) {
sum += arraylist.get(i);
}
return sum;
}
private ArrayList<Integer> contigiousSubArray(int [] array){
ArrayList <Integer> finalList = new ArrayList<Integer>();
int n = array.length;
int minVal = -1000;
for(int i = 0; i<n; i++) {
ArrayList<Integer> aList = new ArrayList<Integer>(); //taking local object of ArrayList
for(int j = i; j<n; j++) {
aList.add(array[j]); //{-2, 1}
int sum = getSum(aList);
//System.out.println(minVal);
if (sum > minVal) {
minVal = sum;
//finalList.clear();
finalList = aList;
System.out.println(sum);
System.out.println(finalList);
}
else continue;
}
}
System.out.println(finalList);
return finalList;
}
public static void main(String[] args) {
FindingSumOfContiguousSubArray cSA = new FindingSumOfContiguousSubArray(); //creating class object
int [] inpArray = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
ArrayList <Integer> contFinalList = cSA.contigiousSubArray(inpArray);
//System.out.println(contFinalList);
//System.out.println(cSA.getSum(contFinalList));
}
}
This code gives output:
[1, -3, 4, -1, 2, 1]
5
[4, -1, 2]
6
[4, -1, 2, 1]
[4, -1, 2, 1, -5, 4]
I am not sure why my arraylist is showing [4, -1, 2, 1, -5, 4] outside the for loop.
I'm not exactly sure what you're looking for here, but maybe try this (you don't need your summing method this way):
private static List<Integer> contigiousSubArray(int [] array){
List<Integer> finalList = new ArrayList<>();
int minVal = Integer.MIN_VALUE;
for(int i = 0; i < array.length; i++) {
List<Integer> aList = new ArrayList<Integer>(); //taking local object of ArrayList
for(int j = i; j < array.length; j++) {
aList.add(array[j]); //{-2, 1}
int sum = aList.stream()
.collect(Collectors.summingInt(Integer::intValue));
//System.out.println(minVal);
if (sum > minVal) {
minVal = sum;
finalList.clear();
finalList.addAll(aList);
}
}
}
return finalList;
}
try this :
public int contigiousSubArray(int[] arr) {
int[] result = new int[arr.length];
result[0]=arr[0];
for (int i = 1; i < arr.length; i++) {
result[i]=Math.max(result[i-1]+arr[i], arr[i]);
}
int maxSumArray = result[0];
for (int j = 1; j if(maxSumArray<result[j])
maxSumArray = result[j];
}
return maxSumArray;
}```
Write a program to print all the LEADERS in the array. An element is leader if it is greater than all the elements to its right side. And the rightmost element is always a leader. For example int the array {16, 17, 4, 3, 5, 2}, leaders are 17, 5 and 2.
Let the input array be arr[] and size of the array be size.
o/p what i am getting is 2 5 17
Note: i want o/p in reverse order , also one below other(line break).
class LeadersInArray
{
/* Java Function to print leaders in an array */
void printLeaders(int arr[], int size)
{
int max_from_right = arr[size-1];
/* Rightmost element is always leader */
System.out.print(max_from_right + " ");
for (int i = size-2; i >= 0; i--)
{
if (max_from_right < arr[i])
{
max_from_right = arr[i];
System.out.print(max_from_right + " ");
}
}
}
public static void main(String[] args)
{
LeadersInArray lead = new LeadersInArray();
int arr[] = new int[]{16, 17, 4, 3, 5, 2};
int n = arr.length;
lead.printLeaders(arr, n);
}
}
Expected output:
17
5
2
Intead of printing those within the loop, add those to a list, and then print those separately.
Following are the changes in your code.
class LeadersInArray {
List<Integer> printLeaders(int[] arr, int size) {
List<Integer> list = new ArrayList<>();
int max_from_right = arr[size - 1];
list.add(max_from_right);
for (int i = size - 1; i >= 0; i--) {
if (max_from_right < arr[i]) {
max_from_right = arr[i];
list.add(max_from_right);
}
}
return list;
}
public static void main(String[] args) {
LeadersInArray lead = new LeadersInArray();
int arr[] = new int[]{16, 17, 4, 3, 5, 2};
List<Integer> integers = lead.printLeaders(arr, arr.length);
for(int i = integers.size()-1; i>=0 ;i--){
System.out.println(integers.get(i));
}
}
}
The my goal is to take a user's input and rotate the array however many times based off of their integer input. At first I was trying to get the array to reverse just to see it shift but I have a few errors in my function that won't let me compile.
Edit: I know I used list instead of using arr. I was looking at an example and accidentally typed it in.
Here is my code:
import java.util.Scanner;
public class Project1P2 {
public static void main(String[] args) {
int[] arr1 = {2,4,6,8,10,12};
int[] arr2 = shift(arr1);
Scanner input = new Scanner(System.in);
System.out.print("Here is the Array: " + arr1);
System.out.println("Enter a number to shift array: ");
int n = input.nextInt();
}
public static int[] shift(int[] arr) {
int[] arrShiftDone = new int[list.length];
for (int i = 0, j = arrShiftDone.length - 1; i < list.length; i++, j--) {
arrShiftDone[j] = list[i];
}
return arrShiftDone;
}
}
You need to fix a couple of things:
shift method never gets called from the main method, which means it won't do anything to the array
shift method should have another argument for the number of places to shift, say n
In shift method, you are using list whereas the argument is declared as arr
Below is an example method that shifts the array:
public static int[] shift(int[] arr, int n) {
if(n > arr.length)
n = n%arr.length;
int[] result = new int[arr.length];
for(int i=0; i < n; i++){
result[i] = arr[arr.length-n+i];
}
int j=0;
for(int i=n; i<arr.length; i++){
result[i] = arr[j];
j++;
}
return result;
}
The compilation error is because the variable list is unknown. Should be using the argument arr instead of list inside the method shift(int[] arr).
You can use Arrays.stream(int[],int,int) method twice to get two streams with the specified ranges of the array: near and far, then swap them and concat back into one stream, and thus get a shifted array:
public static int[] shiftArray(int[] arr, int n) {
return IntStream
.concat(Arrays.stream(arr, n, arr.length),
Arrays.stream(arr, 0, n))
.toArray();
}
public static void main(String[] args) {
int[] arr1 = {2, 4, 6, 8, 10, 12};
System.out.println("Source array: " + Arrays.toString(arr1));
System.out.println("Enter a number: ");
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int[] arr2 = shiftArray(arr1, n % arr1.length);
System.out.println("Shifted array: " + Arrays.toString(arr2));
}
Output:
Source array: [2, 4, 6, 8, 10, 12]
Enter a number:
3
Shifted array: [8, 10, 12, 2, 4, 6]
See also: Place positive numbers before negative
Your mistake is that in your shift method you are using list, it should be arr. I have updated it below. I have also included the shift method.
Edited to include negative shifts.
public static void main(String[] args) {
int[] arr1 = {2, 4, 6, 8, 10, 12};
int[] arr2 = reverseArray(arr1);
Scanner input = new Scanner(System.in);
System.out.println("Here is the Array: " + Arrays.toString(arr1));
System.out.print("Enter a number to shift array: ");
int n = input.nextInt();
int[] arr3 = shiftArray(arr1, n);
System.out.println("Here is the shifted Array: " + Arrays.toString(arr3));
}
public static int[] reverseArray(int[] arr) {
int[] arrShiftDone = new int[arr.length];
for (int i = 0, j = arrShiftDone.length - 1; i < arr.length; i++, j--) {
arrShiftDone[j] = arr[i];
}
return arrShiftDone;
}
public static int[] shiftArray(int[] arr, int shift) {
int[] arrShiftDone = new int[arr.length];
shift = shift % arr.length;
if (shift < 0) {
shift = arr.length + shift;
}
for (int i = 0 + shift, j = 0; j < arr.length; i++, j++) {
if (i >= arr.length) {
arrShiftDone[j] = arr[i - arr.length];
} else {
arrShiftDone[j] = arr[i];
}
}
return arrShiftDone;
}
I am trying to loop through my array and find all the numbers that are repeating more than once:
E.G: if there is 1 1 2 3 4
It should print saying "1 repeats more than once"
Here is my code and so far what I have tried, however it prints all duplicates and keep going, if there is 4 4 4 4 3 6 5 6 9, it will print all the 4's but i dont want that:
class average {
public static void main(String[] args) throws IOException {
int numOfLines = 0;
int sum = 0, mean = 0, median = 0, lq = 0, uq = 0;
int[] buffer;
File myFile = new File("num.txt");
Scanner Scan = new Scanner(myFile);
while(Scan.hasNextLine()) {
Scan.nextLine();
numOfLines++;
}
Scan.close();
Scan = new Scanner(myFile);
System.out.println("Number Of Lines: " + numOfLines);
buffer = new int[numOfLines];
for(int i=0; i<numOfLines; i++) {
buffer[i] = Scan.nextInt();
}
Scan.close();
Scan = new Scanner(myFile);
for(int i=0; i<buffer.length; i++) {
sum = sum+i;
mean = sum/numOfLines;
}
System.out.println("Sum: " + sum);
System.out.println("Mean: " + mean);
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
System.out.println(buffer[k]);
}
}
}
Just add the number you will find duplicated to some structure like HashSet or HashMap so you can find it later when you will detect another duplication.
Set<Integer> printed = new HashSet<Integer>();
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
Integer intObj = new Integer(buffer[k]);
if (!printed.contains(intObj)) {
System.out.println(buffer[k]);
printed.add(intObj);
}
break;
}
}
}
Better O(n) alghorithm:
Set<Integer> printed = new HashSet<Integer>();
for(int i=0; i<buffer.length; i++) {
if (!printed.add(new Integer(buffer[i])) {
System.out.println(buffer[i]);
}
}
You perform the check for every single item of the array, including the first 4, the second 4 and so on. That's why it just doesn't stop and it prints the message multiple times per duplicated element.
You're saying you cannot use a Set and that you don't want to sort your data. My suggestion is that you loop over the array and add each duplicated item to a list. Make sure you check whether the item has already been added. (or use a Set :) )
Then loop over the list and print those items.
I would use a HashMap to store the value I encounter in the array, with the count as a value. So if you encounter a 4, you would look it up in the HashMap, if it doesn't exist, you would add it with a value of 1, otherwise increment the value returned.
You can the loop over the HashMap and get all the values and print the number of duplicates encountered in the array.
Integer[] ints = {1, 1, 2, 3, 4};
System.out.println(new HashSet<Integer>(Arrays.asList(ints)));
Output: [1, 2, 3, 4]
This problem is much simpler and likely faster to solve using a collection. However, as requested here's an answer that uses "just simple array[s]" and no sorting. I've tried not to change your code too much but I refuse to leak resources in the case of an exception.
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
class Average {
public static void main(String[] args) throws IOException {
int numOfLines = 0;
int sum = 0, mean = 0, median = 0, lq = 0, uq = 0;
int[] buffer;
int flag = -1;
File myFile = new File("num.txt");
try (Scanner Scan = new Scanner(myFile)) {
while(Scan.hasNextLine()) {
Scan.nextLine();
numOfLines++;
}
}
try (Scanner Scan = new Scanner(myFile)) {
System.out.println("Number Of Lines: " + numOfLines);
buffer = new int[numOfLines];
for(int i=0; i<numOfLines; i++) {
buffer[i] = Scan.nextInt();
}
}
for(int i=0; i<buffer.length; i++) {
sum = sum+i;
mean = sum/numOfLines;
}
System.out.println("Sum: " + sum);
System.out.println("Mean: " + mean);
//copy every duplicate
int[] dupesOnly = new int[numOfLines];
int dupesOnlyIndex = 0;
for(int i=0; i<buffer.length; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(buffer[k] == buffer[i]) {
dupesOnly[dupesOnlyIndex++] = buffer[i];
//System.out.println(buffer[k]);
}
}
}
//mark all but first occurrence of dupe
boolean[] skip = new boolean[dupesOnlyIndex]; //Inits to false
for (int i = 0; i < dupesOnlyIndex; i++) {
for(int k=i+1; k<buffer.length; k++) {
if(dupesOnly[k] == dupesOnly[i]) {
skip[k] = true;
}
}
}
//skip elements marked as extra dupes
int[] dupesUnique = new int[dupesOnlyIndex];
int dupesUniqueIndex = 0;
for (int i = 0; i < dupesOnlyIndex; i++) {
if (skip[i] == false) {
dupesUnique[dupesUniqueIndex++] = dupesOnly[i];
}
}
//trim to size
int[] dupesReport = new int[dupesUniqueIndex];
for (int i = 0; i < dupesReport.length; i++) {
dupesReport[i] = dupesUnique[i];
}
System.out.println("Dupes: " + Arrays.toString(dupesReport));
}
}
Input file "num.txt" (numbers separated by newlines not commas):
1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3
Output:
Number Of Lines: 14
Sum: 91
Mean: 6
Dupes: [1, 2, 3, 7]
Using the apache commons CollectionUtils.getCardinalityMap(collection):
final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
final List<Integer> list = Arrays.asList(buffer);
final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(list);
for (final Map.Entry<Integer, Integer> entry: cardinalityMap.entrySet()) {
if (entry.getValue() > 1) {
System.out.println(entry.getKey());
}
}
toString() of cardinalityMap looks like this after the init:
{1=4, 2=2, 3=2, 4=1, 5=1, 6=1, 7=2, 9=1}
Using standard java:
final Integer[] buffer = {1, 2, 3, 4, 5, 6, 7, 2, 1, 7, 9, 1, 1, 3};
final List<Integer> list = Arrays.asList(buffer);
final Set<Integer> set = new LinkedHashSet<Integer>(list);
for (final Integer element: set) {
if (Collections.frequency(list, element) > 1) {
System.out.println(element);
}
}
How would one go about filling in an array so that, for example, if you had the following array.
int[] arr = new int[5];
arr[0] = 1;
arr[1] = 3;
arr[2] = 7;
arr[3] = 2;
arr[4] = -4;
so it would look like
arr = {1, 3, 7, 2, -4};
and you would pass it into your method to get a result of
arr = {1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4};
so that you essentially are filling in the numeric gaps. I'd like to make this under the assumption that I don't know how long the array passed in is going to be to make it a more universal method.
my current method looks like such right now...
public static void fillArray(int[] numbers){
int length = numbers.length;
for(int i = 0; i < numbers.length - 1; i ++){
if(numbers[i] <= numbers[i + 1]){
length += numbers[i + 1] - numbers[i];
}else if(numbers[i + 1] < numbers[i]){
length += numbers[i + 1] - numbers[i];
}
}
}
I have length to determine the size of my new array. I think it should work but I'm always down for some input and advice.
Looks like homework, providing algorithm only:
Navigate through the elements of the current array.
Get the distance (absolute difference) between the elements in the array.
Summarize the distances.
Create a new array whose length would be the sum of the distances.
Fill the new array using the elements of the first array and filling the gaps.
Return the array.
Like Luiggi Mendoza said, looks like HW, so here's another algorithm:
insert the first element into a list of integers.
loop on the rest of the elements.
for each two array elements X[i-1], X[i], insert the missing integers to the list
after the loop - use guava to turn the List to array.
This works. just check for array size < 2 for safety.
public static void main(String[] args) {
int[] arr = {1, 3, 7, 2, -4};
Integer[] result = fillArray(arr);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
}
private static Integer[] fillArray(int[] arr) {
List<Integer> list = new ArrayList<Integer>();
list.add(arr[0]);
for (int i = 1; i < arr.length; i++) {
int prevItem = arr[i-1];
int gap = arr[i] - prevItem;
if(gap > 0){
fillGap(list, prevItem, gap, 1);
} else if(gap < 0){
fillGap(list, prevItem, gap, -1);
}
}
return list.toArray(new Integer[0]);
}
private static void fillGap(List<Integer> list, int start, int gap, int delta) {
int next = start+delta;
for (int j = 0; j < Math.abs(gap); j++) {
list.add(next);
next = next+delta;
}
}
Try
import java.util.ArrayList;
import java.util.List;
public class ArrayGap {
public static void main(String[] args) {
int[] arr = {1, 3, 7, 2, -4};
int high, low;
List<Integer> out = new ArrayList<Integer>();
for(int i=0; i<arr.length - 1; i++){
high = arr[i];
if(arr[i] < arr[i+1]){
for(int j=arr[i]; j<arr[i+1]; j++){
out.add(j);
}
} else {
for(int j=arr[i]; j>=arr[i+1]; j--){
out.add(j);
}
}
}
System.out.println(out);
}
}