2D array user input - multidimensional-array

hello everyone i am new to java and i need help on this assignment that our teacher gave us... here is my programm... the objective is everytime i choose a course and time the output will display 1 and everytime the user choose a course or a schedule the output fills up.... sorry if i cant explain it clearly my english is bad.....
import java.io.*;
public class Array2D_input {
public static void main(String[] args)throws IOException {
BufferedReader in= new BufferedReader(new InputStreamReader(System.in));
int X=0;
int num=0;
String [] subject={" ","C#Programming","Autocad","Robotics","JavaProgramming"};
String [] time={" ","8:00 - 12:00","12:00 - 4:00","4:00 - 8:00"};
int [][] N=new int[5][4];
do{
System.out.println("SUBJECT ENROLLMENT\n");
System.out.println("Subjects Offered");
for(int s=1;s<=4;s++)
{
System.out.print(" "+s+" - "+subject[s]);
System.out.println();
}
System.out.println();
System.out.print("YOUR CHOICE : ");
int a=Integer.parseInt(in.readLine());
N[4][a]++;
for(int t=1;t<=3;t++)
{
System.out.print(" "+t+" - "+time[t]);
System.out.println();
}
System.out.print("TIME SCHEDULE : ");
int tm=Integer.parseInt(in.readLine());
num=num+1;
System.out.print("More Entries <Y/N> : ");
X=in.readLine().charAt(0);
}
while(X=='Y');
//System.out.print("\n\tENROLLMENT SUMMARY\n");
System.out.print("\t\t TIME SCHEDULE\n");
System.out.print("SUBJECTS\t 8:00-12:00\t 12:00-4:00\t 4:00-8:00\t total" );
for(int s=0; s<5; s++)
{
System.out.print(""+subject[s]);
System.out.println();
for(int t=0; t<4; t++)
System.out.print("\t\t\t "+N[s][t]);
System.out.println();
}
}
}

Here is the revised code for your task, Hope it will help you.
import java.io.*;
public class Array2D_input {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String x = "";
String[] subject = { "C#Programming", "Autocad", "Robotics", "JavaProgramming" };
String[] time = { "8:00 - 12:00", "12:00 - 4:00", "4:00 - 8:00" };
int[][] N = new int[subject.length][time.length];
// Initializing array with default values
for (int i = 0; i < subject.length; i++) {
for (int j = 0; j < time.length; j++) {
N[i][j] = 0;
}
}
do {
System.out.println("SUBJECT ENROLLMENT\n");
System.out.println("Subjects Offered");
for (int s = 0; s < subject.length; s++) {
System.out.print(" " + (s + 1) + " - " + subject[s]);
System.out.println();
}
System.out.println();
System.out.print("YOUR CHOICE : ");
int a = readNumber(in, subject.length);
for (int t = 0; t < time.length; t++) {
System.out.print(" " + (t + 1) + " - " + time[t]);
System.out.println();
}
System.out.print("TIME SCHEDULE : ");
int tm = readNumber(in, time.length);
N[a - 1][tm - 1]++;
System.out.print("More Entries <Y/N> : ");
x = in.readLine();
} while (x.equalsIgnoreCase("Y"));
// System.out.print("\n\tENROLLMENT SUMMARY\n");
System.out.print("\t\t TIME SCHEDULE\n");
System.out.print("SUBJECTS\t 8:00-12:00\t 12:00-4:00\t 4:00-8:00\t Total");
for (int s = 0; s < subject.length; s++) {
int count = 0;
System.out.println();
System.out.println(subject[s]);
for (int t = 0; t < time.length; t++) {
System.out.print("\t\t " + N[s][t]);
count += N[s][t];
}
System.out.print("\t\t " + count);
}
}
/**
* Function to read input from the console and also check for max value
*
* #param in
* #param maxLimit
* #return
* #throws IOException
*/
public static int readNumber(BufferedReader in, int maxLimit) throws IOException {
int choice = 0;
try {
choice = Integer.parseInt(in.readLine());
} catch (NumberFormatException nf) {
System.out.println("Enter integer only:");
choice = readNumber(in, maxLimit);
}
if (choice > maxLimit) {
System.out.println("Enter only given options");
choice = readNumber(in, maxLimit);
}
return choice;
}
}

java 2d array input example:
//Coded BY Anurag Goel
//Basic 2DArray Program
import java.util.Scanner;
public class array2d {
public static void main(String args [])
{
int [][] arr =new int[5][5];
System.out.println("Enter student roll no and their subject codes");
Scanner o = new Scanner(System.in);
for(int i=0;i<5;i++)
{
System.out.println("Enter "+(i+1)+"th student subject codes ");
for(int k=0;k<5;k++)
{
System.out.println("Enter "+(k+1)+"th subject code : ");
arr[i][k]=o.nextInt();
}
}
for(int j=0;j<5;j++)
{
System.out.print(""+(j+1)+"th student subject codes ");
for(int l=0;l<5;l++)
{
System.out.print(" "+arr[j][l]+" ");
}
System.out.println("");
}
}
}

Related

Sum using recursion

Apologies for the basic question, I'm new to java and have been stuck on this for days.
I need firstly to convert letters to numbers and then using recursion to get the sum of those numbers. I think I am close but I'm also aware it very messy
public static void main(String[] arg) {
String str= "11";
//////////////////////////
String s = "helloworld";
String t = "";
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
if (!t.isEmpty()) {
t += " ";
}
int n = (int)ch - (int)'a' + 1;
t += String.valueOf(n);
}
System.out.println(t);
//////////////////////////////
int sum=0;
int x=Integer.parseInt(t);
int y=recursion(x);
System.out.println("The Sum of the digits is: "+ y);
}
public static int recursion(int y) {
if(y/10>=1) {
int tempvar =y%10;
int remain=y/10;
return tempvar + recursion(remain);
}
else {
return y;
}
}}
Ok so first of all, this line: int x=Integer.parseInt(t); will crash the program in runtime because the string t has spaces in it. So you need to remove this:
if (!t.isEmpty()) {
t += " ";
}
Second, parsing the string t to int is a problem, because the number in string t can get like very, very large. Parsing this very..very large number to an int will also produce an exception during runtime. So a better way to do this is leaving it as a string, loop over it and just add the digits in it.
I have two solutions here:
I loop on t and add the digits.
I assume you have some constraint on the size of t so as it can be parsed to int (or long), and then use recursion as you want.
public class Main {
public static void main(String[] args) {
String s = "hew";
String t = "";
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
int n = (int)ch - (int)'a' + 1;
t += String.valueOf(n);
}
System.out.println("t: "+t);
System.out.println("sum using string: " + getSumUsingString(t));
System.out.println("sum using int: " + getSumUsingLong(Long.parseLong(t), 0));
}
// the string function
private static long getSumUsingString(String t) {
long sum = 0;
for (int i = 0; i < t.length(); i++) {
sum += t.charAt(i)-48;
}
return sum;
}
// recursive function
private static long getSumUsingLong(long num, long sum) {
if (num==0) return sum;
sum += num % 10;
return getSumUsingLong(num / 10, sum);
}
}
Note:
You can use for example, BigInteger class in Java to deal with very large numbers if you really need to parse this string t to a number.

StoreProhibitedCause Exception with linked list on ESP8266

I have implemented a linked list class as follows for storage of sensor data readings.
(Note the total code is ~4000 lines so I can't provide it all, hopefully this gives an idea of what's done).
struct DataItem {
String _dataType;
float _dataArray[dataArraySize_const];
float _calibratedData = -1.0;
float _rawData = -1.0;
DataItem *_next;
uint8_t _dataArraySize = dataArraySize_const;
float *_calibrationParameters;
uint8_t _numCalibrationParameters;
};
class DataContainer {
public:
DataContainer() {
_head = NULL;
_tail = NULL;
};
DataItem* addDataItem(String dataTypeIn, float calibrationParameters[10], uint8_t numberOfCalibrationParameters) {
DataItem *temp = new DataItem;
temp->_dataType = dataTypeIn;
temp->_calibratedData = -1.0;
temp->_rawData = -1.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) { temp->_dataArray[i] = 0; } //Setting all the data array to 0
temp->_calibrationParameters = calibrationParameters;
temp->_numCalibrationParameters = numberOfCalibrationParameters;
temp->_next = NULL;
if(_head == NULL) {
_head = temp;
_tail = temp;
temp = NULL;
}
else {
_tail->_next = temp;
_tail = temp;
}
return temp;
};
uint8_t setDataValue(String dataType, float value, uint8_t arrayIndex) {
DataItem *temp = new DataItem;
temp = _head;
Serial.println("Addresses: ");
while(temp != NULL) {
Serial.print("temp address: 0x");
Serial.println((unsigned long)temp, HEX);
Serial.print("head address: 0x");
Serial.println((unsigned long)_head, HEX);
Serial.print("temp add address: 0x");
Serial.println((unsigned long)&temp, HEX);
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_dataArray[arrayIndex] = value;
float sum = 0.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) {
sum += temp->_dataArray[i];
}
temp->_rawData = sum/dataArraySize_const;
Serial.println("Pre calibration");
this->calibrate(temp);
Serial.println("Finished calibration");
return 0;
};
void calibrate(DataItem *temp) {
temp->_calibratedData = temp->_calibrationParameters[0];
for (uint8_t i = 1; i <= temp->_numCalibrationParameters; i++) {
temp->_calibratedData += temp->_calibrationParameters[i] * pow(temp->_rawData, i);
}
}
uint8_t setCalibrationParameters(String dataType, float calibrationParameters[10]) {
DataItem *temp = new DataItem;
temp = _head;
while(temp != NULL) {
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_calibrationParameters = calibrationParameters;
return 0;
};
private:
DataItem *_head, *_tail;
};
uint8_t numUsedCalibrationParameters = 10;
float calibrationParam[numUsedCalibrationParameters] = {0,1,0,0,0,0,0,0,0,0};
uint8_t dataArrayPosition = 0;
uint8_t dataArraySize = 10;
void setup(void) {
Serial.begin(115200);
Serial.setDebugOutput(false);
delay(20);
Serial.println("\n\nbegin");
pinMode(A0, INPUT);
dataContainer.addDataItem("ADC",calibrationParam,numUsedCalibrationParameters);
void loop(void) {
dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);
if (dataArrayPosition < dataArraySize) { ++dataArrayPosition; }
else { dataArrayPosition = 0; }
delay(100);
}
After around 31000 loops (just under 2^15 which is suspicious to me), I get a StoreProhibitedCause Exception. If I comment out dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);, I no longer get the exception. I suspect it's some way that I have implemented the linked list and it has a memory issue but I have tried printing out the addresses of everything and it doesn't look like anything is running away.
Exception:
Exception (29):
epc1=0x4000df64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
>>>stack>>>
ctx: sys
sp: 3fffec10 end: 3fffffb0 offset: 01a0
3fffedb0: 4024576b 3fff0b08 00000002 40245700
.....
===================== SOLVED =====================
DataItem *temp = new DataItem; should be DataItem *temp; for setDataValue() and setCalibrationParameters().
Otherwise it keeps on creating new structs for every addition.
DataItem *temp = new DataItem; should be DataItem *temp; for setDataValue() and setCalibrationParameters().
Otherwise it keeps on creating new structs for every addition.
(I can't mark it solved without having an answer).

How to split a string using a specific delimiter in Arduino?

I have a String variable and I want to extract the three substrings separeted by ; to three string variables.
String application_command = "{10,12; 4,5; 2}";
I cannot use substring method because this string can be like any of the following or similar patterns also.
String application_command = "{10,12,13,9,1; 4,5; 2}"
String application_command = "{7; 1,2,14; 1}"
The only thing that is common in these patterns is there are three sections separated by ;.
Any insight is much appreciated.
Thank you
I think you need a split-string-into-string-array function with a custom separator character.
There are already several sources on the web and at stackoverflow (e.g. Split String into String array).
// https://stackoverflow.com/questions/9072320/split-string-into-string-array
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = {0, -1};
int maxIndex = data.length()-1;
for(int i=0; i<=maxIndex && found<=index; i++){
if(data.charAt(i)==separator || i==maxIndex){
found++;
strIndex[0] = strIndex[1]+1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}
You can use this function as follows (with ";" as separator):
String part01 = getValue(application_command,';',0);
String part02 = getValue(application_command,';',1);
String part03 = getValue(application_command,';',2);
EDIT: correct single quotes and add semicolons in the example.
The new SafeString Arduino library (available from the library manager) provides a number of tokenizing/substring methods without the heap fragmentation of the String class
See https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
for a detailed tutorial
In this case your can use
#include "SafeString.h"
void setup() {
Serial.begin(9600);
createSafeString(appCmd, 50); // large enought for the largest cmd
createSafeString(token1, 20);
createSafeString(token2, 20);
createSafeString(token3, 20);
appCmd = "{10,12,13,9,1; 4,5; 2}";
size_t nextIdx = 1; //step over leading {
nextIdx = appCmd.stoken(token1, nextIdx, ";}");
nextIdx++; //step over delimiter
nextIdx = appCmd.stoken(token2, nextIdx, ";}");
nextIdx++; //step over delimiter
nextIdx = appCmd.stoken(token3, nextIdx, ";}");
nextIdx++; //step over delimiter
// can trim tokens if needed e.g. token1.trim()
Serial.println(token1);
Serial.println(token2);
Serial.println(token3);
}
void loop() {
}
Also look at pfodParser which parses these types of messages { } for use by pfodApp.
Do not forget to call delete[] to free the memory after the use of the array, that said here is my solution:
String* split(String& v, char delimiter, int& length) {
length = 1;
bool found = false;
// Figure out how many itens the array should have
for (int i = 0; i < v.length(); i++) {
if (v[i] == delimiter) {
length++;
found = true;
}
}
// If the delimiter is found than create the array
// and split the String
if (found) {
// Create array
String* valores = new String[length];
// Split the string into array
int i = 0;
for (int itemIndex = 0; itemIndex < length; itemIndex++) {
for (; i < v.length(); i++) {
if (v[i] == delimiter) {
i++;
break;
}
valores[itemIndex] += v[i];
}
}
// Done, return the values
return valores;
}
// No delimiter found
return nullptr;
}
Here is an example of how to use:
void loop() {
String test = "1,2,3,4,5";
int qtde;
String* t = split(test, ',', qtde);
for (int i = 0; i < qtde; i++) {
Serial.println(t[i]);
delay(1000);
}
delete[] t;
}

QSignalSpy to capture a reference argument

It is not possible to capture an argument that has been passed as reference with a QSignalSpy:
QSignalSpy spy( myObject, SIGNAL(foo(int&)));
...
int& i=spy.at(0).at(0).value<int&>();
Since a QVariant can not contain a reference member. Plain logic.
But are there other solutions to check the passed-in argument?
Since Qt 5, we can simply connect to a lambda function, which makes the use of the QSignalSpy unnecessary:
std::vector<Value> values;
QObject::connect(myObject, &MyObject::foo,
[&](const auto &value)
{ values.emplace_back(value); });
myObject.somethingCausingFoo();
ASSERT_EQ(1u, values.size());
EXPECT_EQ(expectedValue, values.at(0));
An "ugly solution" would be to hack the fairly simple QSignalSpy code in order to handle the reference passed arguments. I provide a minimal working example for int reference arguments. The only changes were made to initArgs and appendArgs functions.
Notice that with this approach you will only be able to check the value of the passed argument by reference. You will not be able to change it's value.
In the initArgs function we check if we have references by argument and we populate the shouldreinterpret list.
void initArgs(const QMetaMethod &member)
{
QList<QByteArray> params = member.parameterTypes();
for (int i = 0; i < params.count(); ++i) {
int tp = QMetaType::type(params.at(i).constData());
if (tp == QMetaType::Void)
{
qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
params.at(i).constData());
// Check if we have a reference by removing the & from the parameter name
QString argString(params.at(i).constData());
argString.remove("&");
tp = QMetaType::type(argString.toStdString().c_str());
if (tp != QMetaType::Void)
shouldReinterpret << true;
}
else
shouldReinterpret << false;
args << tp;
}
}
and the appendArgs function, where we reinterpret the passed by reference arguments:
void appendArgs(void **a)
{
QList<QVariant> list;
for (int i = 0; i < args.count(); ++i) {
QMetaType::Type type = static_cast<QMetaType::Type>(args.at(i));
if (shouldReinterpret.at(i))
{
switch (type)
{
case QMetaType::Int:
list << QVariant(type, &(*reinterpret_cast<int*>(a[i + 1])));
break;
// Do the same for other types
}
}
else
list << QVariant(type, a[i + 1]);
}
append(list);
}
Complete code for reference:
class MySignalSpy: public QObject, public QList<QList<QVariant> >
{
public:
MySignalSpy(QObject *obj, const char *aSignal)
{
#ifdef Q_CC_BOR
const int memberOffset = QObject::staticMetaObject.methodCount();
#else
static const int memberOffset = QObject::staticMetaObject.methodCount();
#endif
Q_ASSERT(obj);
Q_ASSERT(aSignal);
if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE) {
qWarning("QSignalSpy: Not a valid signal, use the SIGNAL macro");
return;
}
QByteArray ba = QMetaObject::normalizedSignature(aSignal + 1);
const QMetaObject *mo = obj->metaObject();
int sigIndex = mo->indexOfMethod(ba.constData());
if (sigIndex < 0) {
qWarning("QSignalSpy: No such signal: '%s'", ba.constData());
return;
}
if (!QMetaObject::connect(obj, sigIndex, this, memberOffset,
Qt::DirectConnection, 0)) {
qWarning("QSignalSpy: QMetaObject::connect returned false. Unable to connect.");
return;
}
sig = ba;
initArgs(mo->method(sigIndex));
}
inline bool isValid() const { return !sig.isEmpty(); }
inline QByteArray signal() const { return sig; }
int qt_metacall(QMetaObject::Call call, int methodId, void **a)
{
methodId = QObject::qt_metacall(call, methodId, a);
if (methodId < 0)
return methodId;
if (call == QMetaObject::InvokeMetaMethod) {
if (methodId == 0) {
appendArgs(a);
}
--methodId;
}
return methodId;
}
private:
void initArgs(const QMetaMethod &member)
{
QList<QByteArray> params = member.parameterTypes();
for (int i = 0; i < params.count(); ++i) {
int tp = QMetaType::type(params.at(i).constData());
if (tp == QMetaType::Void)
{
qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
params.at(i).constData());
QString argString(params.at(i).constData());
argString.remove("&");
tp = QMetaType::type(argString.toStdString().c_str());
if (tp != QMetaType::Void)
shouldReinterpret << true;
}
else
shouldReinterpret << false;
args << tp;
}
}
void appendArgs(void **a)
{
QList<QVariant> list;
for (int i = 0; i < args.count(); ++i) {
QMetaType::Type type = static_cast<QMetaType::Type>(args.at(i));
if (shouldReinterpret.at(i))
{
switch (type)
{
case QMetaType::Int:
int k = (*reinterpret_cast<int*>(a[i + 1]));
list << QVariant(type, &k);
break;
}
}
else
list << QVariant(type, a[i + 1]);
}
append(list);
}
// the full, normalized signal name
QByteArray sig;
// holds the QMetaType types for the argument list of the signal
QList<int> args;
// Holds the indexes of the arguments that
QList<bool> shouldReinterpret;
};

Function from C# to C++ via Qt lib

Could you tell me how these function from C# can be re-written to C++ via Qt lib?
private MemoryStream _memoryStream= new MemoryStream();
//WriteUTFBytes
public void WriteUTFBytes(string value)
{
//Length - max 65536.
UTF8Encoding utf8Encoding = new UTF8Encoding();
byte[] buffer = utf8Encoding.GetBytes(value);
if (buffer.Length > 0)
WriteBytes(buffer);
}
//WriteBytes
public void WriteBytes(byte[] buffer)
{
for (int i = 0; buffer != null && i < buffer.Length; i++)
_memoryStream.WriteByte(buffer[i]);
}
//WriteByte
public void WriteByte(int value)
{
_memoryStream.WriteByte((byte)value);
}
//WriteShort
public void WriteShort(int value)
{
byte[] bytes = BitConverter.GetBytes((ushort)value);
WriteBigEndian(bytes);
}
//WriteBigEndian
private void WriteBigEndian(byte[] bytes)
{
if (bytes == null)
return;
for (int i = bytes.Length - 1; i >= 0; i--)
{
_memoryStream.WriteByte(bytes[i]);
}
}
private:
QBuffer _buffer;
public:
YourClass()
{
_buffer.open(QIODevice::WriteOnly);
}
void writeUtfBytes(const QString &value)
{
QTextStream ts(&_buffer);
ts.setCodec("UTF-8");
ts << value;
}
void writeBytes(const char *data, int size)
{
if (data)
_buffer.write(data, size);
}
void writeByte(int value)
{
_buffer.putChar(value);
}
void writeShort(int value)
{
_buffer.putChar(value >> 8);
_buffer.putChar((char) value);
}

Resources