Is it possible to iterate over a ArrayList adding not all instances but every 12? There are many threads on using addAll to add all instances but not sections.
I currently have an ArrayList containing hundreds of float values:
Snippet:
120.5, 22.2, 76.2, 64.5, 38.3, 27.1, 149.4, 62.3, 127.9, 79.1, 83.4, 68.3, 61.0, 83.4, 5.4, 83.8, 78.3, 111.8, 104.1, 145.2, 94.3, 20.0, 104.7, 35.9, 68.6, 10.1, 41.1, 82.2, 170.7, 17.2, 122.1, 61.0, 46.3, 101.1, 59.0, 30.0, ...
What I want to do is sum the first 12 instances and put this total in a new ArrayList, sum the next 12 instances, store this into the newly created ArrayList and so on. There are exactly 996 instances so i should have 83 new values in this new ArrayList (996/12=83).
Can this be done? If so how? Here is where I have got to...
// ArrayList that contains the float values shown above
public MonthData depthValues() {
ArrayList<Float> rValue = new ArrayList<>();
for (int i = 0; i<months.size(); i++)
{
rValue.add(months.get(i).getDepthMM());
}
System.out.println(rValue);
System.out.println(rValue.size());
return null;
}
//New arrayList im trying to make
//probably done this wrong, help needed here
public MonthData depthTotals() {
ArrayList<Float> depthAdd = new ArrayList<Float>();
int t = 12;
for(int i = 0; i<rValue.size(); ++i)
{
??????????????????
}
}
Any help will be greatly appreciated I cant seem to find anything on this anywhere as I think the sum of all instances is such a popular topic. Its probably a case of iterating properly. In regards to the summing I would have use accumulate in c++, but do not know the equivalent of this in java (if there is one). Thank you for any advice/assistance in advance!
MORE CODE:
public class WeatherStation {
private ArrayList<MonthData> months;
private ArrayList<MonthData> rValue;
private ArrayList<MonthData> depthAdd;
MonthData is a model for data being read to this class it consists on a lot of getters....
public class MonthData {
int y;
int m;
float h;
...
public MonthData(String data) throws Exception {
...
this.parseData(data);
}
void parseData(String csvData) {
String[] parseResult = csvData.trim().split("\\s+");
this.setYear(parseResult[0]);
this.setMonth(parseResult[1]);
...
public String toString() {
return "y =" + year + ", m =" + month + ",...
}
public int getY() {
return y;
}
// followed by lots of getters for: m, h, c, f, r, s, ...
public MonthData depthValues() {
ArrayList<Float> rValue = new ArrayList<>();
for (int i = 0; i<months.size(); i++)
{
rValue.add(months.get(i).getDepthMM());
}
System.out.println(rValue);
System.out.println(rValue.size());
return null;
}
Code recommended:
public MonthData depthTotals() {
ArrayList<Float> depthAdd = new ArrayList<>();
Iterator<Float> it = rValue.iterator();
final int MAX = 12;
while (it.hasNext()){
float sum = 0f;
int counter = 1;
//iterating 12 times
//still check if there is an element in list
while (counter < MAX && it.hasNext()){
sum += it.next();
counter++;
}
depthAdd.add(sum);}
}
ISSUE: Iterator<Float> it = rValue.iterator();
Type mismatch: cannot convert from Iterator<MonthData> to Iterator<Float>
The best way to do this is using Iterator and a counter of 12 by using a while. Here's an example:
List<Float> yourList = ...;
// fill yourList
List<Float> results = new ArrayList<>();
Iterator<Float> it = yourList.iterator();
final int MAX = 12;
while (it.hasNext()) {
float sum = 0f;
int counter = 1;
//iterating 12 times
//still, check if there's an element in your list
while (counter <= MAX && it.hasNext()) {
sum += it.next();
counter++;
}
result.add(sum);
}
I would recommend you use double or Double instead of float as it has around half a trillion times the accuracy.
You can sum every block of 12 like this
public static List<Double> sumBlocks(List<Double> list, int blockSize) {
List<Double> ret = new ArrayList<>();
for(int i = 0; i < list.size(); i += blockSize) {
double sum = 0;
for(int j = 0, len = Math.min(list.size() - i, blockSize); j < len; j++)
sum += list.get(i + j);
ret.add(sum);
}
return ret;
}
and call
List<Double> sums = sumBlocks(list, 12);
Just to demonstrate yet another way to accomplish this:
public static List<Double> sumBlocks(List<Double> list, int blockSize) {
List<Double> result = new ArrayList<>();
double sum = 0d;
for (int i = 0; i < list.size(); i++) {
if (i > 0 && i % blockSize == 0) {
result.add(sum);
sum = 0d;
}
sum += list.get(i);
}
result.add(sum);
return result;
}
Lista<Double> list = // original list
List<Double> ret = new ArrayList<>();
int counter = 0;
double sum = 0;
for (Double f : list) {
if (counter == 12) {
sum = 0;
counter = 0;
ret.add(sum);
}
sum += f;
counter++;
}
// if list is not a multiple of 12
if (list.size() % 12 != 0) {
ret.add(sum);
}
return ret;
try this:
public float total;
for(int i; i < rValue.Size(); i ++)
{
total += rValue[i];
if(i%12=0)
{
add total to new ArrayList
total = 0;
}
}
Arraylist objects inherit the sublist(start, end) method from the List class. You can use myList.sublist(i, j) to access the sublist and get your sum. From there, it should be just simple arithmetic to get your iteration. Inside your for-loop, it should be: myList.sublist(i*12, i*12 + 12).
//Input list
ArrayList<Float> inputList = new ArrayList<Float>();
ArrayList<Float> result = new ArrayList<Float>();
int groupSize = 12;
int offset=0;
while(offset < inputList.size()) {
int toIndex = (inputList.size()-offset)>=groupSize? offset+groupSize : inputList.size();
result.add( listSum(inputList.subList(offset, toIndex)) );
offset += groupSize;
}
Helper method to add items in a list
static float listSum(List<Float> ar) {
float accumulator = 0f;
for(float item:ar) {
accumulator += item;
}
return accumulator;
}
Related
I'm trying to make an average (moy) of an arrayList's column but I need to sum it first, I don't know how to do it
int sumX = 0;
val = new ArrayList<>();
float moy[] = new float[3];
if (i < 100) {
val.add(sensorEvent.values);
i++;
} else {
for (; i > 0; i--);
{
sumX = ?
moy[0] = sumX/100;
}
val.clear();
i = 0;
}
Using DoubleStream:
Variants:
The input is an array of double
double[] values = new double[] {1.1D, 2.33D, 4D};
double average = DoubleStream.of(values).average().getAsDouble();
The input is an ArrayList of Integer
ArrayList<Integer> values = new ArrayList<>();
values.add(1);
values.add(42);
values.add(-1);
double average = values.stream().mapToDouble(value -> (double) value).average().getAsDouble();
You can use this code snippet: (Written in kotlin)
fun main() {
val s: List<Float> = listOf(1.2F, 1.4F, 5.6F)
// populate it with your custom list data
var sum = 0F
s.forEach { it ->
sum+=it
}
println("Sum = $sum and avg = ${sum/(s.size)}")
}
Well here is the java solution:
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
List<Float> s = new ArrayList(Arrays.asList(1.2F, 1.3F, 5.4F, 6.5F));
Float sum = 0F;
for (int i=0; i< s.size(); i++) {
sum+=s.get(i);
}
System.out.println("Sum: "+sum+" and Avg: "+sum/(s.size()));
}
}
Here is how to sum all values in an ArrayList
ArrayList<Integer> nums = new ArrayList<>();
// Populate ArrayList
int sum = 0;
for (int num : nums) {
sum += num;
}
// Do whatever you want with sum after
Just use averaging collector in streams and you don't have to calculate SUM and NUMBER of elements:
ArrayList<Double> numbers = new ArrayList<>() {{
add(1d);
add(2.45d);
add(100d);
}};
final double average = numbers.stream()
.collect(Collectors.averagingDouble(d -> d));
moy[0] = average;
This is my first attempt to use HashMap. Given is a table with n integers. Goal is to calculate in how many common subtables the sum of the numbers is x. I've been trying trying the following. Sample output is 2,10,4. I'm getting 2,10,2. Any idea where I go wrong? Thanks in advance.
public class FindSum {
long count(int[] t, int x) {
HashMap<Integer, Integer> totals = new HashMap<>();
long count = 0;
int sum = 0;
for (int i = 0; i < t.length; i++) {
int value = t[i];
sum += value;
if (totals.containsKey(sum - x)) {
count += totals.get(sum - x);
}
if (value == x) {
count++;
}
totals.put(sum, totals.getOrDefault(sum, 0) + 1);
}
return count;
}
}
Sample output:
FindSum f = new FindSum();
System.out.println(s.count(new int[] {1,3,2,4}, 4)); // 2
System.out.println(s.count(new int[] {0,0,0,0}, 0)); // 10
System.out.println(s.count(new int[] {1,-1,1,-1}, 0)); // 4
I figure I have the general idea down for how to solve the algorithm but the implementation seems to elude me. What I have thus far is this:
public class GreedySalesman {
public static int[] greedySalesmanSolution(int[][] distances) {
List cityList = new ArrayList();
for(int[] array: distances) {
cityList.add(Arrays.asList(array));
}
List<Integer> initialResult = new ArrayList();
initialResult.add(0);
List<Integer> finalResult = findMinDistance(cityList, cityList, initialResult, 0);
/*int finalResultArray = new int[finalResult.size()+1];
int i = 0;
while (!(finalResult.isEmpty)) {
finalResultArray[i] = finalResult.poll();
i++;
}
return finalResultArray;
*/
return null;
}
public static List<Integer> findMinDistance(List<List<Integer>> initialCityInput, List<List<Integer>> cityInput, List<Integer> distanceResult, int index) {
if(cityInput.isEmpty()) {
distanceResult.add(0);
return distanceResult;
}
int min = Collections.min(initialCityInput.get(index));
List<Integer> city = initialCityInput.get(index);
index = city.indexOf(min);
distanceResult.add(index);
cityInput.remove(city);
return findMinDistance(initialCityInput,cityInput,distanceResult,index);
}
}
That is, the algorithm will take an two dimensional array of ints as an input, then make a List cityList referring to distances, then pass it into findMinDistance. The commented out part is where the result from findMinDistance will be converted into an array of ints and returned as finalResultArray but that part is not important yet.
findMinDistance will take in a two dimensional list of Integers twice, a List of Integers that will become the result and an int representing an index.
The function will return the distanceResult when cityInput has been emptied. Otherwise it will start with the first city based on the index, get the minimum distance from that List and its index and add the index to the distanceResult.
Once that has been done, the city will be removed from the cityInput and the program will go into recursion until cityInput has been emptied.
The issue I am getting currently is
I cannot be cast to java.lang.Integer
at
int min = Collections.min(initialCityInput.get(index));
And in main upon trying to run the program with some test data.
Any help will be appreciated.
======
Edit:
I made some changes to my code
public class GreedyTSP {
public int[] greedySalesmanSolution(int[][] distances) {
List<List<Integer>> cityList = new ArrayList();
List<List<Integer>> initialCityList = new ArrayList();
int iLength = distances.length;
for (int i = 0; i < iLength; ++i) {
int jLength = distances[0].length;
cityList.add(new ArrayList(jLength));
initialCityList.add(new ArrayList(jLength));
for (int j = 0; j < jLength; ++j) {
cityList.get(i).add(distances[i][j]);
initialCityList.get(i).add(distances[i][j]);
}
}
List<Integer> initialResult = new ArrayList();
initialResult.add(0);
List<Integer> finalResult = findMinDistance(initialCityList, cityList, initialResult, 0);
int[] finalResultArray = new int[finalResult.size()];
Iterator<Integer> iterator = finalResult.iterator();
for (int i = 0; i < finalResultArray.length; i++){
finalResultArray[i] = iterator.next().intValue();
}
return finalResultArray;
}
public List<Integer> findMinDistance(List<List<Integer>> initialCityInput, List<List<Integer>> cityInput, List<Integer> distanceResult, int initialIndex) {
if(cityInput.isEmpty()) {
distanceResult.add(0);
return distanceResult;
}
List<Integer> city = initialCityInput.get(initialIndex);
Integer min = findMin(city, distanceResult, initialIndex);
int resultIndex = city.indexOf(min);
distanceResult.add(resultIndex);
cityInput.remove(city);
return findMinDistance(initialCityInput,cityInput,distanceResult,resultIndex);
}
public Integer findMin(List<Integer> city, List<Integer> distanceResult, int inputIndex) {
Integer min = Integer.MAX_VALUE;
for(int i = 0; i < city.size();i++) {
if (city.get(i) > inputIndex && city.get(i) < min) min = city.get(i);
}
int resultIndex = city.indexOf(min);
if(distanceResult.contains(resultIndex)) {
return findMin(city, distanceResult, inputIndex);
}
return min;
}
}
Im not having any cast errors at the moment but it seems that the parts of my program dealing with recursion are causing StackOverflowError-s. I've been messing with this thing for literally 16 hours now and I'm all out of ideas as to why. Any ideas?
The problem with your casting is the following
List<List<Integer>> initialCityInput is a List containing Lists with integers.
Therefore initalCityInput.get(index) returns a List not an Int, which cannot be cast to int.
Well, I looked around a bit and I was basically overcomplicating the task through using multidimensional arraylists. I changed the code quite a bit:
public class GreedyTSP {
public static int[] greedySolution(int[][] adjacencyMatrix) {
List<Integer> visitedCities = new ArrayList<>();
int min = Integer.MAX_VALUE;
int startLocation = 0;
int tempStartLocation = 0;
int[] resultArray = new int[adjacencyMatrix.length+1];
visitedCities.add(0);
while(visitedCities.size() < adjacencyMatrix.length ){
for(int i = 0; i < adjacencyMatrix.length; i++){
if(!visitedCities.contains(i) && adjacencyMatrix[startLocation][i] < min){
min = adjacencyMatrix[startLocation][i];
tempStartLocation = i;
}
}
startLocation = tempStartLocation;
visitedCities.add(tempStartLocation);
min = Integer.MAX_VALUE;
}
visitedCities.add(0);
for(int i = 0; i < resultArray.length; i++){
int temp = visitedCities.get(i);
resultArray[i] = temp;
}
return resultArray;
}
}
This will solve the task using a greedy algorithm
I want to get pairs of objects from an ArrayList so I can perform calculations between the elements of each object. Ideally it should iterate over pairs of objects. For example in a List with {obj1, obj2, obj3, obj4} it should go over {obj1,obj2}, {obj2,obj3} and {obj3,obj4}.
What I have tried so far is as follows.
public class Sum {
public ArrayList<Double> calculateSum(ArrayList<Iter> iter) {
ListIterator<Iter> it = iter.listIterator();
ArrayList<Double> sums = new ArrayList<>();
while (it.hasNext()) {
Iter it1 = it.next();
Iter it2;
if(it.hasNext()){
it2 = it.next();
} else { break; }
double sum = it1.getValue() + it2.getValue();
sums.add(sum);
}
return sums;
}
}
Here, it just iterates as {obj1,obj2} and {obj3,obj4}. How can I fix this?
All help is greatly appreciated. Thanks!
A very normal loop, except that you need to loop up to list.size() - 1, the before last element of the array.
public ArrayList<Double> calculateSum(ArrayList<Iter> list) {
ArrayList<Double> sums = new ArrayList<>();
for (int i = 0; i < list.size() - 1; i++) {
double sum = list.get(i).getValue() + list.get(i + 1).getValue();
sums.add(sum);
}
return sums;
}
EDIT
Using an iterator in this case will not be faster than doing a normal loop and just makes the logic unnecessarily complicated and can easily introduce bugs.
A little modification to Davide's answer
for (int i = 0; i < list.size() - 1; i ++) {
sums.add(list.get(i) + list.get(i+1));
}
Because the OP wanted {obj1, obj2} {obj2, obj3} ...etc
Using a iterator
itr = list.iterator();
while(itr.hasNext()) {
Double x = itr.next();
if(itr.hasNext()){
x+= itr.next();
sum.add(x);}
itr.previous();
}
This is not recommended.
Simply use a for loop and stop at element before last one.
for (int i = 0; i < iter.size() - 1; i++) {
Iter first = iter.get(i);
Iter second = iter.get(i + 1);
// Your code here
}
public static ArrayList<Double> calculateSum(ArrayList<Iter> iter) {
ListIterator<Iter> it = iter.listIterator();
ArrayList<Double> sums = new ArrayList<>();
if (it.hasNext()) {
double prev = it.next().getValue();
while (it.hasNext()) {
double current = it.next().getValue();
double sum = prev + current;
sums.add(sum);
prev = current;
}
}
return sums;
}
Try this :-
public ArrayList<Double> calculateSum(ArrayList<Iter> inputList) {
ArrayList<Double> sums = new ArrayList<Double>();
int inputSize = inputList.size(); // size should be saved as an int , instead of calling size() over the list again and again in for loop
int incVar = 1; // 1 incremented value
double sum = 0.0d;
for(int i = 0; incVar < inputSize; i++,incVar++){
sum = inputList.get(i).getValue() + inputList.get(incVar).getValue();
sums.add(sum);
}
return sums;
}
Hi i need some help to improve my code. I am trying to use Radixsort to sort array of 10 numbers (for example) in increasing order.
When i run the program with array of size 10 and put 10 random int numbers in like
70
309
450
279
799
192
586
609
54
657
i get this out:
450
309
192
279
54
192
586
657
54
609
DonĀ“t see where my error is in the code.
class IntQueue
{
static class Hlekkur
{
int tala;
Hlekkur naest;
}
Hlekkur fyrsti;
Hlekkur sidasti;
int n;
public IntQueue()
{
fyrsti = sidasti = null;
}
// First number in queue.
public int first()
{
return fyrsti.tala;
}
public int get()
{
int res = fyrsti.tala;
n--;
if( fyrsti == sidasti )
fyrsti = sidasti = null;
else
fyrsti = fyrsti.naest;
return res;
}
public void put( int i )
{
Hlekkur nyr = new Hlekkur();
n++;
nyr.tala = i;
if( sidasti==null )
f yrsti = sidasti = nyr;
else
{
sidasti.naest = nyr;
sidasti = nyr;
}
}
public int count()
{
return n;
}
public static void radixSort(int [] q, int n, int d){
IntQueue [] queue = new IntQueue[n];
for (int k = 0; k < n; k++){
queue[k] = new IntQueue();
}
for (int i = d-1; i >=0; i--){
for (int j = 0; j < n; j++){
while(queue[j].count() != 0)
{
queue[j].get();
}
}
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
}
}
}
I am also thinking can I let the function take one queue as an
argument and on return that queue is in increasing order? If so how?
Please help. Sorry if my english is bad not so good in it.
Please let know if you need more details.
import java.util.Random;
public class RadTest extends IntQueue {
public static void main(String[] args)
{
int [] q = new int[10];
Random r = new Random();
int t = 0;
int size = 10;
while(t != size)
{
q[t] = (r.nextInt(1000));
t++;
}
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
System.out.println("Radad: \n");
radixSort(q,size,3);
for(int i = 0; i!= size; i++)
{
System.out.println(q[i]);
}
}
}
Hope this is what you were talking about...
Thank you for your answer, I will look into it. Not looking for someone to solve the problem for me. Looking for help and Ideas how i can solve it.
in my task it says:
Implement a radix sort function for integers that sorts with queues.
The function should take one queue as an
argument and on return that queue should contain the same values in ascending
order You may assume that the values are between 0 and 999.
Can i put 100 int numbers on my queue and use radixsort function to sort it or do i need to put numbers in array and then array in radixsort function which use queues?
I understand it like i needed to put numbers in Int queue and put that queue into the function but that has not worked.
But Thank for your answers will look at them and try to solve my problem. But if you think you can help please leave comment.
This works for the test cases I tried. It's not entirely well documented, but I think that's okay. I'll leave it to you to read it, compare it to what you're currently doing, and find out why what you have might be different than mine in philosophy. There's also other things that are marked where I did them the "lazy" way, and you should do them a better way.
import java.util.*;
class Radix {
static int[] radixSort(int[] arr) {
// Bucket is only used in this method, so I declare it here
// I'm not 100% sure I recommend doing this in production code
// but it turns out, it's perfectly legal to do!
class Bucket {
private List<Integer> list = new LinkedList<Integer>();
int[] sorted;
public void add(int i) { list.add(i); sorted = null;}
public int[] getSortedArray() {
if(sorted == null) {
sorted = new int[list.size()];
int i = 0;
for(Integer val : list) {
sorted[i++] = val.intValue(); // probably could autobox, oh well
}
Arrays.sort(sorted); // use whatever method you want to sort here...
// Arrays.sort probably isn't allowed
}
return sorted;
}
}
int maxLen = 0;
for(int i : arr) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
int len = numKeys(i);
if(len > maxLen) maxLen = len;
}
Bucket[] buckets = new Bucket[maxLen];
for(int i = 0; i < buckets.length; i++) buckets[i] = new Bucket();
for(int i : arr) buckets[numKeys(i)-1].add(i);
int[] result = new int[arr.length];
int[] posarr = new int[buckets.length]; // all int to 0
for(int i = 0; i < result.length; i++) {
// get the 'best' element, which will be the most appropriate from
// the set of earliest unused elements from each bucket
int best = -1;
int bestpos = -1;
for(int p = 0; p < posarr.length; p++) {
if(posarr[p] == buckets[p].getSortedArray().length) continue;
int oldbest = best;
best = bestOf(best, buckets[p].getSortedArray()[posarr[p]]);
if(best != oldbest) {
bestpos = p;
}
}
posarr[bestpos]++;
result[i] = best;
}
return result;
}
static int bestOf(int a, int b) {
if(a == -1) return b;
// you'll have to write this yourself :)
String as = a+"";
String bs = b+"";
if(as.compareTo(bs) < 0) return a;
return b;
}
static int numKeys(int i) {
if(i < 0) throw new IllegalArgumentException("I don't deal with negative numbers");
if(i == 0) return 1;
//return (i+"").length(); // lame method :}
int len = 0;
while(i > 0) {
len++;
i /= 10;
}
return len;
}
public static void main(String[] args) {
int[] test = {1, 6, 31, 65, 143, 316, 93, 736};
int[] res = radixSort(test);
for(int i : res) System.out.println(i);
}
}
One thing that looks strange:
for (int p = 0; p < n; p++){
while(queue[p].count() != 0) {
q[p] = (queue[p].get());
}
}
Is p supposed to be the index in q, which ranges from 0 to n-1, or in queue, which ranges from 0 to 9? It is unlikely to be both ...
Another:
for (int index = 0; index < n; index++){
// trying to look at one of three digit to sort after.
int v=1;
int digit = (q[index]/v)%10;
v*=10;
queue[digit].put(q[index]);
}
Why are you multiplying v by 10, only to overwrite it by v = 1 in the next iteration? Are you aware than v will always be one, and you will thus look at the same digit in every iteration?
Well I don't think I can help without almost posting the solution (just giving hints is more exhausting and I'm a bit tired, sorry), so I'll just contribute a nice little fuzz test so you can test your solution. How does that sound? :-)
Coming up with a good fuzztester is always a good idea if you're implementing some algorithm. While there's no 100% certainty if that runs with your implementation chances are it'll work (radix sort doesn't have any strange edge cases I'm aware of that only happen extremely rarely)
private static void fuzztest() throws Exception{
Random rnd = new Random();
int testcnt = 0;
final int NR_TESTS = 10000;
// Maximum size of array.
final int MAX_DATA_LENGTH = 1000;
// Maximum value allowed for each integer.
final int MAX_SIZE = Integer.MAX_VALUE;
while(testcnt < NR_TESTS){
int len = rnd.nextInt(MAX_DATA_LENGTH) + 1;
Integer[] array = new Integer[len];
Integer[] radix = new Integer[len];
for(int i = 0; i < len; i++){
array[i] = rnd.nextInt(MAX_SIZE);
radix[i] = new Integer(array[i]);
}
Arrays.sort(array);
sort(radix); // use your own sort function here.
for(int i = 0; i < len; i++){
if(array[i].compareTo(radix[i]) != 0){
throw new Exception("Not sorted!");
}
}
System.out.println(testcnt);
testcnt++;
}