Binary search in array cannot find number correctly - binary-search

Binary search is not working for number 5,3 and 7 in the array when I change the target value program shows no result.
package com.company;
public class Main {
public static void main(String[] args) {
int[] array = {8, 2, 5, 3, 4, 7, 6, 1,9};
int low=0;
int target=4;
int high=array.length-1;
while (low<=high){
int middle=low+(high-low)/2;
int value=array[middle];
System.out.println(middle);
if(value<target){
low=middle+1;
}
else if(value>target)
high=middle-1;
else
{
System.out.println("found "+middle);
break;
}
}
}
}
what do I need to change in code

The array must be sorted for binary search to work. Try adding Arrays.sort(array); right before the search. (Here's the documentation for that method.)

Related

optaplanner can't get the best solution, and different input orders produce different solutions

I'm trying to make a demo using optaplanner: there are some schemes, each scheme has attribute of gain and cost, and a scheme may conflict with one or more other schemes. The question is to find out a group of schemes which match following constraints:
hard constraint: selected schemea may not conflict with each other in this group
soft constraint: make the difference between total gain and total cost as high as possible
I built following code and try to resolve the question:
#PlanningEntity
#Data
#NoArgsConstructor
public class Scheme {
#PlanningId
private String id;
private int gain;
private int cost;
#PlanningVariable(valueRangeProviderRefs = {"validRange"})
// when valid is ture means this scheme will be selected into the solution group
private Boolean valid;
private Set<String> conflicts = new HashSet<>();
public void addConflict(String id) {
conflicts.add(id);
}
public Scheme(String id, int gain, int cost, String[] conflicts) {
this.id = id;
this.gain = gain;
this.cost = cost;
for (String s : conflicts) {
addConflict(s);
}
}
}
#PlanningSolution
public class SchemeSolution {
private HardSoftScore score;
private List<Scheme> schemeList;
#ProblemFactCollectionProperty
#ValueRangeProvider(id = "validRange")
public List<Boolean> getValidRange() {
return Arrays.asList(Boolean.FALSE, Boolean.TRUE);
}
#PlanningScore
public HardSoftScore getScore() {
return score;
}
public void setScore(HardSoftScore score) {
this.score = score;
}
#PlanningEntityCollectionProperty
public List<Scheme> getSchemeList() {
return schemeList;
}
public void setSchemeList(List<Scheme> schemeList) {
this.schemeList = schemeList;
}
}
And the constraint rule as below:
rule "conflictCheck"
when
Boolean(this==true) from accumulate (
$schs: List() from collect (Scheme(valid==true)),
init(boolean cfl = false;Set cfSet = new HashSet();List ids = new ArrayList()),
action(
for(int i = 0; i < $schs.size(); ++i) {
Scheme sch = (Scheme)$schs.get(i);
cfSet.addAll(sch.getConflicts());
ids.add(sch.getId());
}
for( int i = 0; i < ids.size(); ++i) {
String id = (String)ids.get(i);
if(cfSet.contains(id)) {
cfl = true;
return true;
}
}
),
result(cfl)
)
then
scoreHolder.addHardConstraintMatch(kcontext, -10000);
end
rule "bestGain"
when
$gc : Number() from
accumulate(
Scheme(valid==true, $gain : gain, $cost: cost),
sum($gain - $cost)
)
then
scoreHolder.addSoftConstraintMatch(kcontext, $gc.intValue());
end
Then I constructed three schemes as input of the test. Oddly, I found that optaplanner can't get the best solution, and different input orders produce different solutions.
When I set input as following:
private static List<Scheme> getSchemes() {
List<Scheme> ret = new ArrayList();
ret.add(new Scheme("S1", 5, 2, new String[]{"S3"}));
ret.add(new Scheme("S2", 3, 1, new String[]{"S3"}));
ret.add(new Scheme("S3", 10, 4, new String[]{"S1", "S2"}));
return ret;
}
the output is :
0hard/5soft
Scheme(id=S1, gain=5, cost=2, valid=true, conflicts=[S3])
Scheme(id=S2, gain=3, cost=1, valid=true, conflicts=[S3])
Scheme(id=S3, gain=10, cost=4, valid=false, conflicts=[S1, S2])
And when I set input as following:
private static List<Scheme> getSchemes() {
List<Scheme> ret = new ArrayList();
ret.add(new Scheme("S3", 10, 4, new String[]{"S1", "S2"}));
ret.add(new Scheme("S1", 5, 2, new String[]{"S3"}));
ret.add(new Scheme("S2", 3, 1, new String[]{"S3"}));
return ret;
}
I get the best solution and the output is :
0hard/6soft
Scheme(id=S3, gain=10, cost=4, valid=true, conflicts=[S1, S2])
Scheme(id=S1, gain=5, cost=2, valid=false, conflicts=[S3])
Scheme(id=S2, gain=3, cost=1, valid=false, conflicts=[S3])
Could anyone help me about it?

PDF- Can text chunk contains 2 or more words?

Im using LocationTextExtractionStrategy to render text from PDF.
Text is rendered in function called RenderText.
So my question is: Can one chunk contains more than 2 words ?
For example we have text:
'MKL is a helpfull person'
Can it be written in chunks like (the most important chunk is bolded):
MK
L
is a h
elpfull
per son
?
Below is the code i use for word separation.
Im doing the word separation during adding text(chunk from renderText function) to current line.
public class TextLineLocation
{
public float X { get; set; }
public float Y { get; set; }
public float Height { get; set; }
public float Width { get; set; }
private string Text;
private List<char> bannedSings = new List<char>() {' ',',', '.', '/', '|', Convert.ToChar(#"\"), ';', '(', ')', '*', '&', '^', '!','?' };
public void AddText(TextInfo text)
{
Text += text;
foreach (char sign in bannedSings)
{
//creating new word
if (text.textChunk.Text.Contains(sign))
{
string[] splittedText = text.textChunk.Text.Split(sign);
foreach (string val in splittedText)
{
//if its first element, add it to current word
if (splittedText[0] == val)
{
// if its space, just ignore...
if (splittedText[0] == " ")
{
continue;
}
wordList[wordList.Count - 1].Text += val;
wordList[wordList.Count - 1].Width += text.getFontWidth();
wordList[wordList.Count - 1].Height += text.getFontHeight();
}
else
{
//if it isnt a first element, create another word
wordList.Add(new WordLocation(text.textChunk.StartLocation[1], text.textChunk.StartLocation[0], text.getFontWidth(), text.getFontHeight(), val));
//TODO: what if chunk has more than 2 words separated ?
}
}
}
}
else
{
//update last word
wordList[wordList.Count-1].Text += text.textChunk.Text;
wordList[wordList.Count - 1].Width += text.getFontWidth();
wordList[wordList.Count - 1].Height += text.getFontHeight();
}
}
public List<WordLocation> wordList = new List<WordLocation>();
}
Not sure from what library LocationTextExtractionStrategy comes, or what it does exactly, but in the PDF representation itself you can group characters together in a "chunk".
How this is used totally depends on the program that produces the PDF: Some programs keep words together, some programs only group word fragments (for example for kerning), some program do other, random things.
So, if LocationTextExtractionStrategy returns these as chunks, you can't rely on anything. If LocationTextExtractionStrategy doesn't return these, but instead relies on spacing heuristics to group characters into chunks, then this will be as good as the heuristics are.
Bottom line: A PDF doesn't contain text, and contains glyphs and their position on the page. Trying to reconstruct text from it is and remains guesswork. You may get it to work in the majority of cases, but there'll always be PDFs where whatever you are doing fails.

How do I properly write out a JUnit test for a method that counts how many e's are in a string?

Here is the method I have defined that is supposed to accept a String as input and should return the number of times the char 'e' occurs as an int:
public int count_e(String input){
int count = 0;
for (int i = 0;i<input.length();i++){
char e = 'e';
if (input.charAt(i)==e){
count=count+1;
i++;
return count;
}
else{
count=count+1;
i++;
}
}
return count;
}
}
I am trying to write a JUnit test to see if I can input a string into the method and return the correct number of e's. Below is my test, and at the moment I keep getting an error saying that my method count_e is undefined for type String.
Can someone tell me why it is coming up as undefined?
#Test
public void testCount_e() {
String input= "Isabelle";
int expected= 2;
int actual=input.count_e();
assertTrue("There are this many e's in the String.",expected==actual);
}
}
You failed to pass anything to your count_e method!
How about something like:
#Test
public void testCount_e() {
String input = "Isabelle";
int expected = 2;
int actual = count_e(input);
Assert.assertEqual("There are this many e's in the String.", expected, actual);
}
For a unit test, you could probably shorten it to:
#Test
public void testCount_e() {
Assert.assertEqual("There are this many e's in the String.", count_e("Isabelle"), 2);
}

CDT : Parsing enumerations, enumerators and corresponding values

I'm developing an extension of eclipse CDT plug-in which has to parse the c++ code and find all
enumerations (names)
enumerators (names)
enumerator values (numbers)
Suppose .cpp file contains following text
enum SomeEnum
{
One = 0,
Two = 1,
Three = 2,
Four = 3,
maxNum
};
The pluging should output following :
Enumeration - SomeEnum
Enumerators - One, Two, Three, Four, maxNum
Values - 0, 1, 2, 3,
The visitor method of ASTVisitor inherited class finds the enumerations this way
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTDeclSpecifier specifier = ((IASTSimpleDeclaration)declaration).getDeclSpecifier();
if (specifier instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumSpecifier = (IASTEnumerationSpecifier)specifier;
IBinding binding = enumSpecifier.getName().resolveBinding();
System.out.println(enumSpecifier.getName());
}
}
return PROCESS_CONTINUE;
}
Question : How can I iterate over the enumerators and their corresponding values of found enumeration ?
Well figured out on my own
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTDeclSpecifier specifier = ((IASTSimpleDeclaration)declaration).getDeclSpecifier();
if (specifier instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumSpecifier = (IASTEnumerationSpecifier)specifier;
// Get the current enumeration name
String enumerationName = enumSpecifier.getName().toString();
IASTEnumerator[] enumerators = enumSpecifier.getEnumerators();
for (IASTEnumerator enumerator : enumerators)
{
System.out.println(enumerator.getName());
if (enumerator.getValue() instanceof IASTLiteralExpression ) {
System.out.println(enumerator.getValue());
}
}
}
}
return PROCESS_CONTINUE;
}

JUnit testing method with assertions

The isSorted() instance method in class A has a bug:
public class A {
private int[] a;
public A(int[] a) { this.a = a; }
/** Return true if this A object contains an array sorted
* in nondecreasing order; else false. */
public boolean isSorted() {
for(int i=1; i<a.length-1; i++) {
if(a[i] < a[i-1]) return false;
}
return true;
}
}
Write a JUnit test method testIsSorted() which will fail because of this bug, but will pass when the bug is fixed.
(Assume that there is no setUp() method defined.)
This is the answer:
public void testIsSorted() {
int[] array = {2, 1};
A haha = new A(array);
assertFalse(haha.isSorted);
}
first of all where is the bug, i cannot seem to located it.
Secondly shoudn't it be assertTrue(haha.isSorted)
because when its assertFalse it will pass because the array is in descending order, therefore the isSorted will return false and assertFalse(false) will return true where-as assertTrue(false) will return false.
The bug is on the line
for(int i=1; i<a.length-1; i++) {
Since array indexes start at 0, the definition of i should be int i=0, not 1. The index 1 points to the second element of the array.
The assertFalse statement checks that the isSorted() method returns false for the given array {2,1}. The isSorted() method checks that no entry is less than the previous one (conversely, each entry is greater than or equal to the previous one). In the example, it will return false, because 2 at index 0 is greater than 1 at index 1. Therefore, the assertFalse is the correct assertion for the case.
You could also test like this (note the reversed order of array).
public void testIsSorted() {
int[] array = {1, 2};
A haha = new A(array);
assertTrue(haha.isSorted());
}