I have added few number into the arraylist . I would want to find the certain value from it.Example i have 4,4,9,9,18. I would like to find the value of 26. If 26 > largest value in the list it will display 18 and if value is 17 it will display 9, and if value is 5 it will display 4. Also is there another method to implement this search because liner search might be slow.
search value 26
[4,4,9,9,18] display 18
[20,20,29,29,4] display 20
[28,28,28,1,10] display 28
if you have this list and search 26, it will output the first element. because the first element is <= than the value being search.
but current output is
Value of value2 : 9
public class Arraylist {
public static ArrayList<Integer> aList;
public static void main(String[] args) {
aList = new ArrayList<Integer>();
aList.add(4);
aList.add(4);
aList.add(9);
aList.add(9);
aList.add(18);
int value = 26;
int value2 = 0;
for (int i = 0; i < aList.size(); i++) {
if (aList.get(i) <= value) {
if (i + 1 < aList.size()) {
value2 = aList.get(i);
} else if(i > aList.size()) {
value2 = aList.get(i);
}
}
}
System.out.println("Value of value2 : " + value2);
}
}
I have written the code using an array. You can easily adopt it to ArrayList
int a[] = {28,28,28,1,10};
// int a[] = {20,20,29,29,4}; // other input of yours
// int a[] = {4,4,9,9,18};
int x = 26;
int liVal = -1;
for(int i=0; i<a.length;i++)
if(x < a[i]) // if we met a value > x
{
if(liVal==-1) // if we could not find any largest value smaller than x
liVal = a[i]; // return the value > x
break;
}
else if(x > a[i]) // find the largest value smaller than x,
{
if(liVal < a[i])
liVal = a[i];
}
System.out.println(liVal);
A trivial and un-optimized version:
int value = 26 // or whatever parameter you get
int retVal = Integer.MIN_VALUE;
for (int i : list) {
if (i <= value && i > retVal) {
retVal = i;
}
}
return retVal;
If the array is sorted you can use a variant of binary search.
see http://en.wikipedia.org/wiki/Binary_search_algorithm
Once you sort the list, binarySearch in Collections will do the trick:
Collections.sort(aList)
int index = Collections.binarySearch(aList)
If index is nonnegative, the number was found in the list, and index is the position. If it is negative, it wasn't found, but index indicates where it would be if it were in the list.
And with O(log n) runtime for the search.
If I understand correctly, you want to find the biggest number in your array that is smaller or equal to value. I would do it like this:
for (int i = 0; i < aList.size(); i++) {
if ( aList.get(i) <= value && aList.get(i) > value2) {
value2 = aList.get(i);
}
}
Also in your example, you do value2 = 0. This is ok if you can guarante that the array only contains positive values. Otherwise it would be better to use value2 = Integer.MIN_VALUE.
Finally, this code assume that the array is not guarantied to be sorted and that you will only need to search it once. Otherwise, a binary search could be more performant. Other answers on this question already show how to accomplish that.
According to the OP's comments:
The list isn't sorted
if value < min return min
if value > max return max
if min <= value <= max return nearest val <= value
public static int findValue(List<Integer> list, int value){
int min = Integer.MAX_VALUE, nearest = Integer.MIN_VALUE;
for(Integer v : list){
if(v == value)
return value;
if(v > nearest && v < value)
nearest = v;
if(v < min)
min = v;
}
return value < min ? min : nearest;
}
As a side note, you don't need to keep track of the max because nearest = max if value > max(list).
Related
I am reading Java Shildt The Complete reference and I am wondering about one piece of code thats looks very simple, but I can't understand how it works.
// A generic interface example.
// A Min/Max interface.
interface MinMax<T extends Comparable<T>> {
T min();
T max();
}
// Now, implement MinMax
class MyClass<T extends Comparable<T>> implements MinMax<T> {
T[] vals;
MyClass(T[] o) {
vals = o;
}
// Return the minimum value in vals.
public T min() {
T v = vals[0];
for (int i = 1; i < vals.length; i++)
if (vals[i].compareTo(v) < 0) v = vals[i];
return v;
}
// Return the maximum value in vals.
public T max() {
T v = vals[0];
for (int i = 1; i < vals.length; i++)
if (vals[i].compareTo(v) > 0) v = vals[i];
return v;
}
}
class GenIFDemo {
public static void main(String args[]) {
Integer inums[] = {3, 6, 2, 8, 6};
Character chs[] = {'b', 'r', 'p', 'w'};
MyClass<Integer> iob = new MyClass<Integer>(inums);
MyClass<Character> cob = new MyClass<Character>(chs);
System.out.println("Max value in inums: " + iob.max());
System.out.println("Min value in inums: " + iob.min());
System.out.println("Max value in chs: " + cob.max());
System.out.println("Min value in chs: " + cob.min());
}
}
//The output is shown here:
//Max value in inums: 8
//Min value in inums: 2
//Max value in chs: w
//Min value in chs: b
I can't understand this one and its output:
// Return the maximum value in vals.
public T max() {
T v = vals[0];
for (int i = 1; i < vals.length; i++)
if (vals[i].compareTo(v) > 0) v = vals[i];
return v;
}
Why the output is 8, if according to the condition,
vals[1].compareTo(vals[0])(6>3) > 0 is already true,
so v = 6, not 8.
I can't understand how it finds the max and min value here..
Could you please explain it? Thanks!
Only for the iteration where i=1, vals[1].compareTo(vals[0]) comparison is done, in which case v=6. Consider the case i=3 for the given for-loop. Here vals[3], which is 8, is compared with the value of v (which is 6 since it was updated before). Since 8 is larger than 6, the value of v is updated to 8 in this iteration.
v holds the max value and starts with the first one.
The loop iterates over the remaining elements and sets the value to v if vals[i].compareTo(v) > 0 (which means vals[i] is greater than v).
So not only the first two elements are compared.
According to this reference,
a.compareTo(b)
returns a positive value if and only if a is to be regarded strictly larger than b, which means that
// Return the maximum value in vals.
public T max() {
T v = vals[0];
for (int i = 1; i < vals.length; i++)
if (vals[i].compareTo(v) > 0) v = vals[i];
return v;
}
actually determines the maximum where v is the candidate for the maximum. If vals[i].compareTo(v) is larger than zero, this means that v[i] is larger that the candidate for the maximum. Consequently, v ist assigned vals[i], as vals[i] is the new candidate for the maximum.
New to programming: In Java, what is the best way to get each individual digit of an Integer and its position for comparisons? For example, with an input of an Integer i = 12345, I'd like to preform a comparison operation on each individual digit 1, 2, 3, 4, and 5. Since I can't get the index of the integer, I converted the integer to string, iterated, and used charAt().
String sI = Integer.toString(i);
for(int j = 0; j<i; j++){
if(charAt(j)>n){
//do something
}
}
why not try this... you will know that your int is printing from the last digit so you'll know the position.
public static void main(String[] args) {
Integer temp = 123456789;
do {
System.out.println(temp % 10);
temp = temp / 10;
} while (temp % 10 > 0);
}
I would do the same solution however your loop may result in some unexpected errors. That's because i can be greater than the length of your String sI.
And chars in Java are integers too so the comparison may fail: for example the character value of 1 is 49 so a comparison like if (sI.charAt(j) > 10) will always results in true. So you have to re-convert your character to an integer with the Character.getNumericValue() function.
So I'd change the loop to the following:
String sI = Integer.toString(i);
for(int j = 0; j < sI.length(); j++){
if(Character.getNumericValue(sI.charAt(j)) > n){
//do something
}
}
May be something like this helps
public int findallIntegers(int x, int n) {
if(x < 1) return 1;
if(x%10 > n) {
//do some thing
}
return findallIntegers(x/10, n);
}
So the problem that I'm trying to solve is where you have an array of stock prices where each position is a different stock price. Now the problem is writing an algorithm to calculate the span of the stock which basically means each i position contains the number of previous stocks that were either less than or equal to the current stock. This is what I have right now:
public static int[] stockSpan(int[] stock) {
int[] span = new int[stock.length];
for (int i = 0; i < stock.length; i++) {
int index = i - 1;
span[i] = 1;
while (index >= 0 && stock[index] <= stock[i]) {
span[i] += span[index];
index -= span[index];
}
}
return span;
}
What I'm trying to do now is use stacks to try and improve the running time of this to O(n). The thing is I'm more used to using for loops and arrays to solve this problem so how do I implement stacks into this algorithm?
Solution Source
Stock Span problem: For a given array P of stock prices the stock span is the maximum number of consecutive days the price of the stock has been less than or equal to its price on day i. This can be solved efficiently using a stack.
public static int[] computeSpan(int[] P) {
int length = P.length;
int[] S = new int[P.length];
MyStack<Integer> myStack = new MyStack<>(length);
int h = 0;
for (int i = 0; i < length; i++) {
h = 0;
while (!myStack.isEmpty()) {
if (P[i] >= P[myStack.top()]) {
myStack.pop();
} else {
break;
}
}
h = myStack.isEmpty() ? -1 : myStack.top();
S[i] = i - h;
myStack.push(i);
}
return S;
}
Please go through the link for solution reference.
Try this solution :
public static Map<Integer, Integer> getStockSpan(int[] prices) {
Map<Integer, Integer> stockSpan = new HashMap<>();
Stack<Integer> span = new Stack<>();
for (int price : prices) {
int count = 1;
while (!span.isEmpty() && price >= span.peek()) {
count += stockSpan.get(span.pop());
}
span.push(price);
stockSpan.put(price, count);
}
return stockSpan;
}
here is my code in C++ using stack library
#include <iostream>
#include <stack>
using namespace std;
void CalculateSpan(int a[],int n,int S[]){
stack<int> st;
//create the stack
int i;
st.push(0); //pushed first element of ARRAY to stack
//as there is nothing to the left of initial element set its span as 1 to default
S[0]=1;
for(i=1;i<n;i++){
//start looping from index 1
//basically we are comparing initial element with all other element
//now initially if top of stack is less than ith index of array then just pop
while(!st.empty()&&a[st.top()]<=a[i])
st.pop();
if(st.empty())
S[i]=i+1;
else
//to get span if ith index greater then top then just substract ith from top index and push the ith index
S[i]=i-st.top();
st.push(i);
}
}
void printa(int arr[],int n){
int i;
for(i=0;i<n;i++){
cout<<arr[i];
}
}
int main()
{
int a[10],S[10];
int n,i;
cout<<"Enter the size of the element you want";
cin>>n;
cout<<"\nEnter the number of elements you want\n";
for(i=0;i<n;i++){
cin>>a[i];
}
CalculateSpan(a,n,S);
printa(S,n);
}
perform these operation n times :
1) two get the value u need to calculate
res = i-R+1
where i is current index and R is the index popped from stack
2) do following
i) if stack is not empty and current element is >= to the element at top index then do following
while stack is not empty and current element is >= to the a[top] do pop()
ii) push the current index to the stack and calculate the value
int *a, *res;
a = new int[n];
res = new int[n];
stack<int>S;
for(int i=0;i<n;i++){
int top = i;
if(!S.empty() && a[S.top()]<=a[i]) {
while(!S.empty() && a[S.top()]<=a[i]){
top = S.top();
S.pop();
}
S.push(top);
}
S.push(i);
res[i] = i-top+1;
}
I have 2 ArrayLists. The first contains 993 float values. I have added every 12 instances of these 993 float values together and stored them in another ArrayList (993/12), giving the second ArrayList a size of 83.
Here is a snippet of the second ArrayList:
919.2, 927.9, 809.39996, 633.8, 626.8, 871.30005, 774.30005, 898.8, 789.6, 936.3, 765.4, 882.1, 681.1, 661.3, 847.9, 683.9, 985.7, 771.1, 736.6, 713.2001, 774.49994, ...
The first of these values i.e 919.2 corresponds to the year 1930.
The second, 927.9 corresponds to the year 1931.
The third, 809.39996 corresponds to the year 1932 and so on... meaning the last 83rd value will correspond to 2012.
The ultimate aim I have is to look at these values in this second ArrayList and find the largest, printing its value AND the year that corresponds with it.
The issue is the program currently has no way of knowing these corresponding year values.
Allowed assumption: the first corresponding year value is 1930.
Currently I am able to successfully print the largest value in the ArrayList which is half the problem.
To achieve this is simply sorted the ArrayList:
System.out.println(depthAdd.get(depthAdd.size() -1));
What im lacking is the corresponding year. How can I do this???
Here is some code for you:
public void depthValues() {
ArrayList<Float> rValue = new ArrayList<>();
...
ArrayList<Float> depthAdd = new ArrayList<>();
Iterator<Float> it = rValue.iterator();
final int MAX = 12;
while(it.hasNext()) {
float sum = 0f;
int counter = 1;
while (counter <= MAX && it.hasNext()) {
sum += it.next();
counter++;
}
depthAdd.add(sum);
}
Collections.sort(depthAdd);
System.out.println("Wettest year: //year needs to go here "
+ depthAdd.get(depthAdd.size() -1));
return;
}
You could copy the original List (before sorting). And then iterate again to determine matching position(s). Another option is to create a custom class to contain the year and the value, and create a custom Comparator on the ammount of rainfall. The first might be implemented like
List<Float> depthCopy = new ArrayList<>(depthAdd);
Collections.sort(depthAdd);
Float max = depthAdd.get(depthAdd.size() - 1);
for (int i = 0; i < depthCopy.size(); i++) {
if (depthCopy.get(i).equals(max)) {
System.out.println("Wettest year: " + (1930 + i) + " "
+ depthAdd.get(depthAdd.size() - 1));
}
}
Just keep track of the index and maximum value in separate variables:
float maxValue;
int maxIndex;
while (it.hasNext()) {
float sum = 0f;
int counter = 1;
while (counter <= MAX && it.hasNext()) {
sum += it.next();
counter++;
}
if (sum > maxValue) {
maxValue = sum;
maxIndex = depthAdd.size(); // The current index
}
depthAdd.add(sum);
}
Then print the value:
System.out.println("The max was " + maxValue + " in " + (1930 + maxIndex));
If you need/want to store the value pairs you could use something like Map<Integer, Float> and directly reference the key value pair after sorting. Otherwise, either of the previous answers should work.
Float max = depthAdd.get(0);
int index = 0;
for (int i = 1; I < r.size(); i++)
if (depthAdd.get(i) > max) {
max = depthAdd.get(i);
index = i;
}
int year = 1930 + index;
And max will be the biggest value;
It sounds like you want a key,value pair. That's a job for a Map, not a List.
Map<Integer,Float> depthAdd = new HashMap<Integer,Float>();
...
int year = 1930;
while(it.hasNext()) {
float sum = 0f;
int counter = 1;
while (counter <= MAX && it.hasNext()) {
sum += it.next();
counter++;
}
depthAdd.put(year, sum);
year++;
}
...
I am trying to write code to return the lowest number of coins needed to make up a given number. The inputs to my method are an array of valid coins, and the number I try to make.
public static int change(int[] d, int p) {
int[] tempArray = new int[p + 1]; // tempArray to store set
// of coins forming
// answer
for (int i = 1; i <= p; i++) { // cycling up to the wanted value
int min = Integer.MAX_VALUE; // assigning current minimum number of
// coins
for (int value : d) {// cycling through possible values
if (value <= i) {
if (1 + tempArray[i - value] < min) { // if current value is
// less than min
min = 1 + tempArray[i - value];// assign it
}
}
}
tempArray[i] = min; // assign min value to array of coins
}
return tempArray[p];
}
This works for most cases, however, when I fill in the following :
int[] test = {2,3,4};
System.out.println("answer = " + change(test, 6));
The answer should be 2, right? But it prints out :
-2147483647
What have I missed?
Because, during the first iteration tempArray[i] = min; tempArray[i] is assigned to MAX, and during subsequent iteration[s], min = 1 + tempArray[i - value]; would try to increment MAX by one, which basically shifts the bits and forms a negative counterpart.