Recursive call is not terminating for Binary Search - recursion

Could someone tell me what I am doing wrong? My recursive call is not terminating when it sees the "return mid" but it continues to execute the remaining conditions.
public class BinSearch {
public static int binSearch(int[] a, int key, int low, int high){
if (low >= high){
System.out.println("Low = High");
return -1;
}
int mid = low + ((high - low)/2);
//System.out.println("Value of Mid for low:"+low+", high:"+high+" is:"+mid);
if (a[mid] == key){
System.out.println("Value of mid is:"+a[mid]);
return mid;
}
else if (a[mid] < key){
binSearch(a, key, mid+1, high);
}
else {
binSearch(a, key, low, high)
}
System.out.println("I am somehow out of the loop!");
return -1;
}
public static void main (String[] args){
System.out.println("Hello World");
int[] arr = {1, 6, 9, 13, 22, 27, 29 , 38, 49, 50, 61, 72};
int key = 22;
int high = arr.length;
int response = binSearch(arr, key, 0, high);
System.out.println("The response is"+ response);
}
}

It looks like you get the value of mid but then it is not saved and not used, so everytime it gets to the end of binSearch and outputs -1. You might want to make binSearch a helper function for the binary search, and instead of recursively calling binSearch, you could return binSearch(a, key, low, high). Also, intead of returning binSearch(a, key, low, high), you might want to return the lower half of the array by returning binSearch(a, key, low, mid-1). The function should return -1 when low is greater than high. Your code looks good and hope that helps!
public class BinSearch {
public static int Search(int[] a, int key){
return binSearch(a, key, 0, a.length-1);
}
public static int binSearch(int[] a, int key, int low, int high){ //make this the helper function
if (low > high){
System.out.println("Low = High");
return -1;
}
int mid = low + ((high - low)/2);
//System.out.println("Value of Mid for low:"+low+", high:"+high+" is:"+mid);
if (a[mid] == key){
System.out.println("Value of mid is:"+a[mid]);
return mid;
}
else if (a[mid] < key){
//add return
return binSearch(a, key, mid+1, high);
}
else {
//add return and return for lower part of array
return binSearch(a, key, low, mid-1);
//return binSearch(a, key, low, high);
}
/*System.out.println("I am somehow out of the loop!");
return -1;*/
}
public static void main (String[] args){
System.out.println("Hello World");
int[] arr = {1, 6, 9, 13, 22, 27, 29 , 38, 49, 50, 61, 72};
int key = 22;
int high = arr.length;
int response = Search(arr, key);
//binSearch(arr, key, 0, high);
System.out.println("The response is"+ response);
}
}

Related

Arduino is giving a weird output when using toInt()

I'm trying to convert a string to an integer (which is actually a binary number) so that I can output the DEC value, but where the answer SHOULD be 63 (00111111), it's giving me -19961 as an output? It would be great if someone can help me correctly convert the string to an int :)
// C++ code
//
const int button = 13;
int buttonPressed = 0;
int counter = 0;
int myInts[] = {0, 0, 1, 1, 1, 1, 1, 1};
void setup()
{
Serial.begin(9600);
pinMode(button, INPUT);
}
void loop()
{
buttonPressed = digitalRead(button);
if (buttonPressed == HIGH){
counter = count();
//rial.println(counter);
}
else{
Serial.println("Button not pressed");
}
delay(1000);
}
int count()
{
String myString = ""; //Empty string for constructing
int add = 0;
int i = 0;
//Should add all the values from myInts[] into a string
while(i < 8){
myString = String(myString + myInts[i]);
Serial.println(add);
delay(1000);
add++;
i++;
}
Serial.println(myString);
int myNumber = myString.toInt(); //Convert the string to int
Serial.println(myNumber, DEC); //Should print 63 in this case
return add;
}
Your code currently does the following:
Concatenates all your integers together to make a string "00111111"
Attempts to convert it (as a string holding a base 10 integer) to the integer 111,111 (one hundred eleven thousand, one hundred eleven)
Hits integer overflow. The range of an Arduino int is -32768 to 32767 (65536 possible values), so the number you really have is 111111 - 2*65536 = -19961.
I don't believe that there's an overload of Arduino's ToInt that converts a binary string to an integer. Depending on the C++ support in Arduino, you may be able to use std::stoi as described here.
Instead, you may choose to do the conversion yourself - you can keep track of a number sum, and at each loop iteration, double it and then add the next bit:
int sum = 0;
for(int i = 0; i < 8; i++) {
sum *= 2;
sum += myInts[i];
// print and delay if you want
}
Over the eight iterations, sum ought to have values 0, 0, 1, 3, 7, 15, 31, and finally 63

Stumped. Bool values from class objects are returning ascending integers?

Lot of code to post because I can't really tell where the issue is. I am trying to run this on an ESP32 chip and am writing the code in vscode with platformio.
The function
byte _previousPoint(){
for (byte point = 0; point < maxPoints; point ++){ //loop through active points.
if (_points[point + 1].getActive() != 1){
return point;
}
else {
long t1 = point_seconds(point);
long t2 = point_seconds(point + 1);
if (t1 <= currentTime){ //If current time is after this point.
if (t2 > currentTime){ //If current time is less than the next point (it is sandwiched).
return point;
}
}
}
}
return 0;
}
Is not behaving as I expect. And it seems the cause is that the function
bool getActive(){
return _active;
}
under the class point is returning not a bool but ascending numbers for each channel. point.getActive() should return a bool value, and that bool value should default to 0 (as it is set in the class definition), which is why this makes no sense. The point that is returning the erroneous values is the last one in the _points[maxPoints] array for each channel, and that value seems to match the channel numbers (for red it is 0, for green it is 1, for blue it is 2, etc.)
If I print the value _active upon running the point.setActive() function it comes out correctly. So something is wrong with "getting" it later.
Here is full code below. Let me know if you need some clarification because I know it's a lot. And thanks for anybody patient enough to help.
#include <Arduino.h>
long currentTime;
long lastUp;
byte totalChannels = 4;
const byte maxPoints = 3;
class point {
public:
point(){
}
void clear(){
_active = 0;
_day = 0;
_hour = 0;
_minute = 0;
_second = 0;
_intensity = 0;
_mode = 0;
}
bool getActive(){
return _active;
}
uint getDay(){
return _day;
}
byte getHour(){
return _hour;
}
byte getMinute(){
return _minute;
}
byte getSecond(){
return _second;
}
int getIntensity(){
return _intensity;
}
byte getMode(){
return _mode;
}
void setActive(bool active){
_active = active;
}
void setDay(uint day){
_day = day;
}
void setHour(byte hour){
_hour = hour;
}
void setMinute(byte minute){
_minute = minute;
}
void setSecond(byte second){
_second = second;
}
void setIntensity(byte intensity){
_intensity = intensity;
}
void setMode(byte mode){
_mode = mode;
}
private:
bool _active = 0;
uint _day = 0;
byte _hour = 0;
byte _minute = 0;
byte _second = 0;
int _intensity = 0;
byte _mode = 0;
};
class channel {
public:
channel(String color, byte pin){
this->_color = color;
this->_pin = pin;
init();
};
void setpoint(byte row, point &newPoint, uint day, byte hour, byte minute, byte second, byte intensity, byte mode){ //edits points (for debug)
newPoint.setDay(day);
newPoint.setHour(hour);
newPoint.setMinute(minute);
newPoint.setSecond(second);
newPoint.setIntensity(intensity);
newPoint.setMode(mode);
newPoint.setActive(1);
_points[row] = newPoint;
}
bool getPoint(byte point){
return _points[point + 1].getActive();
}
void clearAllPoints(){
for (byte point = 0; point < maxPoints; point ++ ){
_points[point].clear();
}
}
void setPin(byte pin){
_pin = pin;
}
byte getPin(){
return _pin;
}
uint getIntensity(){
byte point1 = _previousPoint();
byte point2 = _nextPoint(point1);
byte fade_mode = _points[point1].getMode();
uint intensity;
if (point2 != 0){
if (fade_mode == 0){
intensity = _interpolate_lin(point1, point2);
}
else if (fade_mode == 1){
intensity = _interpolate_sin(point1, point2);
}
}
else if (point2 != 1){
if (fade_mode == 0){
intensity = _interpolate_lin(point1, point2);
}
else if (fade_mode == 1){
intensity = _interpolate_sin(point1, point2);
}
}
return intensity;
}
private:
//class attributes
point _points[maxPoints]; //points maximum of 64 points per channel.
byte _pin; //PWM pin output for channel
String _color; //LED color
float _interpolate_lin(byte point1, byte point2){
float idiff = _points[point2].getIntensity() - _points[point1].getIntensity();
float tdiff = point_seconds(point2) - point_seconds(point1);
float m;
if (tdiff != 0){
m = idiff / tdiff;
}
else{
m = 0;
}
float t = currentTime - point_seconds(point1);
float b = _points[point1].getIntensity();
//linear equation result
float i = (m * t) + b;
return i;
}
float _interpolate_sin(byte point1, byte point2){
float amplitude = _points[point2].getIntensity() - _points[point1].getIntensity();
float tdiff = point_seconds(point2) - point_seconds(point1);
float a = (-0.5 * amplitude);
float b = (2 * PI) / (2 * tdiff);
float t = (currentTime - point_seconds(point1));
float d = 0.5 * abs(amplitude);
//cosine equation result
float i = (a * cos(b * t)) + d;
return i;
}
byte _previousPoint(){
for (byte point = 0; point < maxPoints; point ++){ //loop through active points.
if (_points[point + 1].getActive() != 1){
return point;
}
else {
long t1 = point_seconds(point);
long t2 = point_seconds(point + 1);
if (t1 <= currentTime){ //If current time is after this point.
if (t2 > currentTime){ //If current time is less than the next point (it is sandwiched).
return point;
}
}
}
}
return 0;
}
byte _nextPoint(byte point){
if (_points[point + 1].getActive() != 1){ //if next point is inactive, previous is last in cycle. Next point is 0.
return 0;
}
else if (_points[point + 1].getActive() == 1){ //if next point is active, return it as _nextPoint.
return point + 1;
}
return 0;
}
long point_seconds(byte point){
return ((_points[point].getHour() * 3600) + (_points[point].getMinute() * 60) + _points[point].getSecond());
}
};
//declaring channels and initializing channel array.
channel red("red", 0);
channel green("green", 1);
channel blue("blue", 2);
channel royal("royal blue", 3);
channel *channels[] = {
&red,
&green,
&blue,
&royal
};
void setIntensities(){
for (byte ch = 0; ch < totalChannels; ch ++){
channel ledChannel = *channels[ch];
byte intensity = ledChannel.getIntensity();
ledcWrite(ledChannel.getPin(), intensity);
}
}
void setup() {
Serial.begin(9600);
//set up LED outputs
ledcAttachPin(12, 0);
ledcAttachPin(13, 1);
ledcAttachPin(16, 2);
ledcSetup(0, 1000, 8);
ledcSetup(1, 1000, 8);
ledcSetup(2, 1000, 8);
//clear all points
for (byte ch = 0; ch < totalChannels; ch++){
channel ledChannel = *channels[ch];
ledChannel.clearAllPoints();
}
//Set points for testing purposes
point red1;
point red2;
point red3;
point green1;
point green2;
point green3;
point blue1;
point blue2;
point blue3;
point royal1;
point royal2;
point royal3;
red.setpoint(0, red1, 0, 0, 0, 0, 0, 0);
red.setpoint(1, red2, 0, 0, 0, 10, 255, 0);
red.setpoint(2, red3, 0, 0, 0, 20, 0, 0);
green.setpoint(0, green1, 0, 0, 0, 10, 0, 0);
green.setpoint(1, green2, 0, 0, 0, 20, 255, 0);
green.setpoint(2, green3, 0, 0, 0, 30, 0, 0);
blue.setpoint(0, blue1, 0, 0, 0, 20, 0, 0);
blue.setpoint(1, blue2, 0, 0, 0, 30, 255, 0);
blue.setpoint(2, blue3, 0, 0, 0, 40, 0, 0);
royal.setpoint(0, royal1, 0, 0, 0, 30, 0, 0);
royal.setpoint(1, royal2, 0, 0, 0, 40, 255, 0);
royal.setpoint(2, royal3, 0, 0, 0, 50, 0, 0);
Serial.print("red: "); // <----------These are to debug. The channels are returning ascending bool values for point 3 (which should all be 0)
for (byte point = 0; point < 3; point++){
Serial.print(red.getPoint(point));
}
Serial.print(" green: ");
for (byte point = 0; point < 3; point++){
Serial.print(green.getPoint(point));
}
Serial.print(" blue: ");
for (byte point = 0; point < 3; point++){
Serial.print(blue.getPoint(point));
}
Serial.print(" royal: ");
for (byte point = 0; point < 3; point++){
Serial.print(royal.getPoint(point));
}
}
void loop() {
currentTime = millis() / 1000;
if (currentTime > lastUp){
setIntensities();
lastUp = currentTime;
}
}
The problem is with your getPoint() method:
bool getPoint(byte point){
return _points[point + 1].getActive();
}
You're referencing the array with point + 1 instead of point so when you attempt to read the last item in the array you're actually reading off the end of the array and getting arbitary data.
Just change this to:
bool getPoint(byte point){
return _points[point].getActive();
}
You're also doing the same thing on your _previousPoint() method:
byte _previousPoint(){
for (byte point = 0; point < maxPoints; point ++){ //loop through active points.
if (_points[point + 1].getActive() != 1){
return point;
}
Again - I think you want to just replace [point + 1] with [point] to go through the list of points and prevent reading past the end of the array.

Print only 7 last numbers from long long int

I have hex value ex. 0300E0678C, i convert it to long long int 12899608460 but on this stage I must print only 7 last numbers from long long int - 9608460, so I try to sprintf with %lld but it returns nothing.
Any ideas how to do it?
#include <SoftwareSerial.h>
#include <ID20Reader.h>
#include <PriUint64.h>
int rx_pin = 3;
int tx_pin = 2;
char output[16];
long long int numer;
char buf[50];
ID20Reader rfid(rx_pin, tx_pin);
void setup() {
Serial.begin(9600);
tone(4, 3400, 1000);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
rfid.read();
if(rfid.available())
{
digitalWrite(LED_BUILTIN, HIGH);
String code = rfid.get();
Serial.println(code);
tone(4, 4000, 500);
char bufor[12];
code.toCharArray(bufor,12);
Serial.println(bufor);
numer = hexToDec(bufor);
Serial.println(PriUint64<DEC>(numer));
delay(500);
digitalWrite(LED_BUILTIN, LOW);
}
}
long long hexToDec(String hexString) {
long long decValue = 0;
int nextInt;
for (int i = 0; i < hexString.length(); i++) {
nextInt = int(hexString.charAt(i));
if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
nextInt = constrain(nextInt, 0, 15);
decValue = (decValue * 16) + nextInt;
}
return decValue;
}
I do:
...
byte myData[16];
int i = 0;
...
numer = hexToDec(bufor);
i=0;
do
{
byte y = numer % 10;
myData[i] = y;
numer = numer / 10;
i++;
}
while (numer != 0);
for (int i = 6; i >= 0; i--)
{
Serial.print(myData[i]);
}
And first tests are optimistic ;)
Try something like this should do the trick:
#include <iostream>
#include <string>
int main()
{
// Example given
constexpr long long int p = 0x300E0678C;
std::printf("Example: %lld\n", p);
// Create new string with p
std::string tempStr(std::to_string(p), 0);
long long int pLast7 = std::atoll( // Convert string to long long integer
tempStr.substr(tempStr.length() - 7, 7) // cut the string 7 characters from the end, and have the next 7 characters returned
.c_str()); // convert it to C-style string (const char*) for use with atoll
std::printf("Last 7: %lld\n", pLast7);
}
Here is the cpp.sh link in case you wanted to try it out for yourself!
cpp.sh/53evd

Using a distance sensor in Processing to control the attributes of shapes

I'm trying to make a program that will use the readings it gets from a distance sensor to control the attributes of circles (size, xy and colour). To do this I'm trying to make it record the current value and apply that to the value when you press the relevant key (Eg. press 's' and it changes the size to whatever the distance was at that point). - Ideally I'd like the circle to change whatever field is next dynamically as you move your hand over the sensor, but that seems a bit beyond me.
I've tried to do as much as I can, but everything I'm not sure of I've commented out. Any tips or advice? I'm really not sure what I'm doing when it comes to classes and constructors.
EDIT: When I run the code, nothing happens.
import processing.serial.*;
int xpos, ypos, s, r, g, b;
Circle circle;
int shapeSize, distance;
String comPortString;
Serial myPort;
void setup(){
size(displayWidth,displayHeight); //Use entire screen size.
//Open the serial port for communication with the Arduino
myPort = new Serial(this, "/dev/cu.usbmodem1411", 9600);
myPort.bufferUntil('\n'); // Trigger a SerialEvent on new line
}
void draw(){
background(0);
delay(50); //Delay used to refresh screen
println(distance);
}
void serialEvent(Serial cPort){
comPortString = (new String(cPort.readBytesUntil('\n')));
if(comPortString != null) {
comPortString=trim(comPortString);
/* Use the distance received by the Arduino to modify the y position
of the first square (others will follow). Should match the
code settings on the Arduino. In this case 200 is the maximum
distance expected. The distance is then mapped to a value
between 1 and the height of your screen */
distance = int(map(Integer.parseInt(comPortString),1,200,1,height));
if(distance<0){
/*If computer receives a negative number (-1), then the
sensor is reporting an "out of range" error. Convert all
of these to a distance of 0. */
distance = 0;
}
}
}
void keyPressed()
{
// N for new circle (and keep old one)
if((key == 'N') || (key == 'n')) {
println("n");
circle = new Circle(1,1,1,1,1,1);
}
//r - change red
if((key == 'R') || (key == 'r')) {
float red = map(distance, 0, 700, 0, 255);
r = int(red);
println("r " + r);
}
//g - change green
if((key == 'G') || (key == 'g')) {
float green = map(distance, 0, 700, 0, 255);
g = int(green);
println("g " + g);
}
//b - change blue
if((key == 'B') || (key == 'b')) {
float blue = map(distance, 0, 700, 0, 255);
b = int(blue);
println("b " + b);
}
//S - change Size
if((key == 'S') || (key == 's')) {
s = distance;
println("s " + s);
}
//X - change x pos
if((key == 'X') || (key == 'x')) {
xpos = distance;
println("x " + xpos);
}
//y - change y pos
if((key == 'Y') || (key == 'y')) {
ypos = distance;
println("y " + ypos);
}
}
class Circle {
Circle(int xpos, int ypos, int s, int r, int g, int b){
ellipse(xpos, ypos, s, s);
color(r, g, b);
}
int getX(){
return xpos;
}
int getY(){
return ypos;
}
}
I would split this into steps/tasks:
Connecting to the Arduino
Reading values from Arduino
Mapping read values
Controlling mapping
You've got the Arduino part pretty much there, but things look messy when trying to map read values to the circle on screen.
For now, for simplicity reasons, let's ignore classes and focus on simply drawing a single ellipse with x,y,size,r,g,b properties.
To get read of jitter you should update the property ellipse continuously, not just when pressing a key. On the key event you should simply change what property gets updated.
You could use extra variables to keep track of what ellipse properties you're updating.
Here's a refactored version of the code based on the points above:
import processing.serial.*;
int xpos,ypos,s,r,g,b;
int distance;
int propertyID = 0;//keep track of what property should be updated on distance
int PROP_XPOS = 0;
int PROP_YPOS = 1;
int PROP_S = 2;
int PROP_R = 3;
int PROP_G = 4;
int PROP_B = 5;
void setup(){
size(400,400);
//setup some defaults to see something on screen
xpos = ypos = 200;
s = 20;
r = g = b = 127;
//initialize arduino - search for port based on OSX name
String[] portNames = Serial.list();
for(int i = 0 ; i < portNames.length; i++){
if(portNames[i].contains("usbmodem")){
try{
Serial arduino = new Serial(this,portNames[i],9600);
arduino.bufferUntil('\n');
return;
}catch(Exception e){
showSerialError();
}
}
}
showSerialError();
}
void showSerialError(){
System.err.println("Error connecting to Arduino!\nPlease check the USB port");
}
void draw(){
background(0);
fill(r,g,b);
ellipse(xpos,ypos,s,s);
}
void serialEvent(Serial arduino){
String rawString = arduino.readString();//fetch raw string
if(rawString != null){
String trimmedString = rawString.trim();//trim the raw string
int rawDistance = int(trimmedString);//convert to integer
distance = (int)map(rawDistance,1,200,1,height);
updatePropsOnDistance();//continously update circle properties
}
}
void updatePropsOnDistance(){
if(propertyID == PROP_XPOS) xpos = distance;
if(propertyID == PROP_YPOS) ypos = distance;
if(propertyID == PROP_S) s = distance;
if(propertyID == PROP_R) r = distance;
if(propertyID == PROP_G) g = distance;
if(propertyID == PROP_B) b = distance;
}
void keyReleased(){//only change what proprty changes on key press
if(key == 'x' || key == 'X') propertyID = PROP_XPOS;
if(key == 'y' || key == 'Y') propertyID = PROP_YPOS;
if(key == 's' || key == 'S') propertyID = PROP_S;
if(key == 'r' || key == 'R') propertyID = PROP_R;
if(key == 'g' || key == 'G') propertyID = PROP_G;
if(key == 'b' || key == 'B') propertyID = PROP_B;
}
//usually a good idea to test - in this case use mouseY instead of distance sensor
void mouseDragged(){
distance = mouseY;
updatePropsOnDistance();
}
If this makes sense, it can easily be encapsulated in a class.
We could use an array to store those properties, but if something like props[0] for x, props1 for y, etc. is harder to read, you could use an IntDict which allows you to index values based on a String instead of a value (so you can do props["x"] instead of props[0]).
Here's an encapsulated version of the code:
import processing.serial.*;
Circle circle = new Circle();
void setup(){
size(400,400);
//initialize arduino - search for port based on OSX name
String[] portNames = Serial.list();
for(int i = 0 ; i < portNames.length; i++){
if(portNames[i].contains("usbmodem")){
try{
Serial arduino = new Serial(this,portNames[i],9600);
arduino.bufferUntil('\n');
return;
}catch(Exception e){
showSerialError();
}
}
}
showSerialError();
}
void showSerialError(){
System.err.println("Error connecting to Arduino!\nPlease check the USB port");
}
void draw(){
background(0);
circle.draw();
}
void serialEvent(Serial arduino){
String rawString = arduino.readString();
if(rawString != null){
String trimmedString = rawString.trim();
int rawDistance = int(trimmedString);
int distance = (int)map(rawDistance,1,200,1,height);
circle.update(distance);
}
}
void keyReleased(){
circle.setUpdateProperty(key+"");//update the circle property based on what key gets pressed. the +"" is a quick way to make a String from the char
}
//usually a good idea to test - in this case use mouseY instead of distance sensor
void mouseDragged(){
circle.update(mouseY);
}
class Circle{
//an IntDict (integer dictionary) is an associative array where instead of accessing values by an integer index (e.g. array[0]
//you access them by a String index (e.g. array["name"])
IntDict properties = new IntDict();
String updateProperty = "x";//property to update
Circle(){
//defaults
properties.set("x",200);
properties.set("y",200);
properties.set("s",20);
properties.set("r",127);
properties.set("g",127);
properties.set("b",127);
}
void draw(){
fill(properties.get("r"),properties.get("g"),properties.get("b"));
ellipse(properties.get("x"),properties.get("y"),properties.get("s"),properties.get("s"));
}
void setUpdateProperty(String prop){
if(properties.hasKey(prop)) updateProperty = prop;
else{
println("circle does not contain property: " + prop+"\navailable properties:");
println(properties.keyArray());
}
}
void update(int value){
properties.set(updateProperty,value);
}
}
In both examples you can test the distance value by dragging your mouse on the Y axis.
Regarding the HC-SR04 sensor, you can find code on the Arduino Playground to get the distance in cm. I haven't used the sensor myself yet, but I notice other people has some issues with it, so it's worth checking this post as well. If you want to roll your own Arduino code, no problem, you can use the HC-SR04 datasheet(pdf link) to get the formula:
Formula: uS / 58 = centimeters or uS / 148 =inch; or: the range = high
level time * velocity (340M/S) / 2; we suggest to use over 60ms
measurement cycle, in order to prevent trigger signal to the echo
signal.
It's important to get accurate values (you'll avoid jitter when using these to draw in Processing). Additionally you can use easing or a moving average.
Here's a basic moving average example:
int historySize = 25;//remember a number of past values
int[] x = new int[historySize];
int[] y = new int[historySize];
void setup(){
size(400,400);
background(255);
noFill();
}
void draw(){
//draw original trails in red
stroke(192,0,0,127);
ellipse(mouseX,mouseY,10,10);
//compute moving average
float avgX = average(x,mouseX);
float avgY = average(y,mouseY);
//draw moving average in green
stroke(0,192,0,127);
ellipse(avgX,avgY,10,10);
}
void mouseReleased(){
background(255);
}
float average(int[] values,int newValue){
//shift elements by 1, from the last to the 2nd: count backwards
float total = 0;
int size = values.length;
for(int i = size-1; i > 0; i--){//count backwards
values[i] = values[i-1];//copy previous value into current
total += values[i];//add values to total
}
values[0] = newValue;//add the newest value at the start of the list
total += values[0];//add the latest value to the total
return (float)total/size;//return the average
}

Finding Largest value in an array using recursion

This is my test array
int [] A = {1,2,7,3,5,6};
this is the method
public static int largest(int [] A)
{
int temp = A[0];
return largestRec(A, 0, A.length - 1, temp);
}
// WRITE THIS METHOD that returns the largest of the elements in A
// that are indexed from low to high. RECURSIVELY!
private static int largestRec(int [] A, int low, int high, int temp)
{
if (low == high)
return A[low];
if (low <= A.length){
if (A[low] > temp){
temp = A[low];
}
largestRec(A, low+1, high, temp);
}
return temp
}
Why does the tem reset and return A[0] which is 1?
The problem is that you are not doing anything with the return value of the recursive call to largestRec. Remember that parameters are pass by value (even in recursive calls to the same function) so changing it inside the function does not affect the outside.
I don't think you should be passing the temp as a parameter at all.
private static int largestRec(int [] A, int low, int high )
{
int temp;
if (low == high)
temp = A[low];
else
{
temp = largetstRec( A, low+1, high );
if (A[low] > temp){
temp = A[low];
}
}
return temp;
}
That keeps temp local to the function (which I think is what you probably meant be calling it temp in the first place).
private static int largestRec(int [] A, int low, int high){
var largest = A[low];
if(low == high)
return largest; // or A[high] because both are same
for(var i = low; i < high; i++){
if(largest < A[i])
largest = A[i];
}
return largest;
}

Resources