类的数据成员为数组,怎么样根据键盘输入的数据顺序建立对象?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类的数据成员为数组,怎么样根据键盘输入的数据顺序建立对象?相关的知识,希望对你有一定的参考价值。

建立一个CInverse类,能够存储整型变量,并可算出其逆序数,例如234的逆序数为432;至多输入10个整型数字(以0结束),以输入的顺序建立对象,并在对象生命期结束前打印出整数和其逆序数,例如输入12,234,0则应输出12,21

234,432。
就是这一题,如果我定义一个类cinverse,数据成员为int数组,那怎么样根据键盘输入的数据建立对象?

//建立一个CInverse类,能够存储整型变量,
//并可算出其逆序数,例如234的逆序数为432;
//至多输入10个整型数字(以0结束),以输入的顺序建立对象,
//并在对象生命期结束前打印出整数和其逆序数,例如输入12,234,0则应输出12,21
// 234,432。

#include<ctype.h>
#include "Inverse.h"
#include <iostream>
#include <tchar.h>
#include <string>
#include <stack>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])

int input;
CInverse inve[10];
while(cin>>input,input!=0)

CInverse inve(input);

return 0;

-----CInverse Inverse.h
#ifndef CIVERSE_H_H_H_H_H_H
#define CIVERSE_H_H_H_H_H_H
class CInverse

private:
int m_iData;
public:
CInverse():m_iData(0)
CInverse(int iData):m_iData(iData)
void inverse(int &iRel);//inverse Integer
friend istream& operator>>(istream &in, CInverse &inv);//overload >>
friend ostream& operator<<(ostream &out,const CInverse &inv);//overload<<
~CInverse();
;
void
CInverse::inverse(int &iRel)

//inverse Integer
iRel=0;
int temp=m_iData;//temp variale
stack<int> intStack;//define a stack
while(temp!=0)
//push to stack
intStack.push(temp%10);
temp/=10;

int place=1;
while(!intStack.empty())
//invert data
iRel+=place*intStack.top();
intStack.pop();
place*=10;


istream&
operator>>(istream &in,CInverse &inv)

//overload >>
cout<<"Input a Integer:"<<endl;
in>>inv.m_iData;
return in;

ostream&
operator<<(ostream &out,const CInverse &inv)

//overload<<
out<<inv.m_iData<<" "<<flush;
return out;


CInverse::~CInverse()

if(this->m_iData!=0)
cout<<*this;
int iData;
inverse(iData);
if(iData!=0)
cout<<iData<<" "<<flush;

#endif

参考资料:欢迎指教,标准答案,在线等楼主给分,谢谢

参考技术A 请到专业论坛提出此问题,这里只适合解决菜鸟级计算机类科学类问题。 参考技术B 很基本的一个数据结构问题吧~ 用C++实现的话直接用STL 里边的list vector 就可以了。
思路是用栈结构,先进后出! 建议找本数绝结构的书 看栈 队列那一章节
参考技术C #include <iostream>

using namespace std;

class Clnverse
private:
int array[10];
int state ;
private:
int track(int n)
char num[6];
char ret[6];
sprintf(num,"%d",n);
for(int i = strlen(num) - 1,j = 0 ; i >= 0 ; i--,j++)
ret[j] = num[i];

return atoi(ret);

public:
void push(int n)
array[state++] = n;

void output()
for(int i = 0 ; i < state ; i++)
cout << array[i] <<"," << track(array[i]) << endl;


;
int main()
int n;
Clnverse app;
cin >> n;
while(n!=0)
app.push(n);
cin >> n;

app.output();
return 0;

没做判断,功能是有的。
参考技术D 去http://www.csdn.net/问问吧。肯定能解决问题,里面都是高手。

如何根据java中的输入数据顺序/名称动态调用不同的setter方法?

我班上有大约20个变量。我需要读取excel表,然后相应地获取数据并根据变量的名称在DTO类中设置它。除2外,所有变量都是字符串。那些2是数字的。现在我将从excel获得单行,接下来我必须获取每个单元格的内容并根据单元格的数据/索引的顺序显式调用setter方法。有没有办法自动化这个?我的意思是任何方法为特定索引调用特定方法?我们可以在某个数组中定义它的关系并将它们联系起来吗?

请帮忙。

答案

Assumptions

  1. 假设3,而不是20个变量。
  2. 假设您的Excel工作表包含以下列: 第1列=姓名 第2栏=街道 第3列=数字。
  3. 假设下面是你的那个类: package com.johanw.stackoverflow.dynamicinit; public class MyObjectImpl {private String name;私人弦街;私有int号; public MyObjectImpl() { } public MyObjectImpl(String name, String street, int number) { this.name = name; this.street = street; this.number = number; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public void setNumberAsString(String number) { this.number = Integer.valueOf(number); } }

我想到了两种不同的解决方案。

Solution 1

  1. 第一个解决方案是使用反射和按照要初始化对象的顺序排序的方法名称列表,如下面的代码所示...... package com.johanw.stackoverflow.dynamicinit; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class PopulateObjects2 {interface InitialiseFieldAction {void initialise(MyObjectImpl object,String value); } private static String[] initMethods = { "setName", "setStreet", "setNumberAsString" }; private static Method getMethod(int index) throws NoSuchMethodException { if ((index < 0) || (index > initMethods.length - 1)) return null; Class clazz = MyObjectImpl.class; return clazz.getMethod(initMethods[index], String.class); } public static MyObjectImpl retrieveWithValues(String[] values) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { if (values.length != initMethods.length) return null; // Handle the fact you don't have the same amount of initialisations as the amount of fields MyObjectImpl o = new MyObjectImpl(); for (int i = 0; i < initMethods.length; i++) { Method m = getMethod(i); m.invoke(o, values[i]); } return o; } }

Solution 2

第二种解决方案是使用以下模式,使用InitialiseFieldAction实现列表。请注意,在解决方案2中,我不使用setNumberAsString方法,而是在InitialiseFieldAction的实现中将字符串转换为数字。

package com.johanw.stackoverflow.dynamicinit;

public class PopulateObjects1 {

    interface InitialiseFieldAction {
        void initialise(MyObjectImpl object, String value);
    }

    private static InitialiseFieldAction[] initActions = new InitialiseFieldAction[] {
            new InitialiseFieldAction() { public void initialise(MyObjectImpl o, String value) { o.setName(value);} },
            new InitialiseFieldAction() { public void initialise(MyObjectImpl o, String value) { o.setStreet(value);} },
            new InitialiseFieldAction() { public void initialise(MyObjectImpl o, String value) { o.setNumber(Integer.valueOf(value));} },
    };

    public static MyObjectImpl retrieveWithValues(String[] values) {
        if (values.length != initActions.length) return null;   // Handle the fact you don't have the same amount of initialisations as the amount of fields
        MyObjectImpl o = new MyObjectImpl();
        for (int i = 0; i < initActions.length; i++) {
            initActions[i].initialise(o, values[i]);
        }
        return o;
    }
}

Usage

  • 对于工作表中的每一行,从左到右创建一个字符串数组,表示每列的值。
  • 然后调用PopulateObjects1 / 2.retrieveWithValues(该数组)。
  • 它将返回使用该数组初始化的对象,如使用initActions动态配置。在这种情况下,InitialiseFieldAction实现。

Test

我添加了下面的单元测试,它允许a)测试b)了解如何使用代码。

package com.johanw.stackoverflow.dynamicinit.init;

import org.junit.Assert;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Optional;
import org.junit.Assert;
import org.junit.Test;

public class PopulateObjects {
    private String[] exampleRow = { "name", "street", "10"};

    @Test
    public void method1() {
        MyObjectImpl o = PopulateObjects1.retrieveWithValues(exampleRow);
        Assert.assertTrue(o.getName().equals("name"));
        Assert.assertTrue(o.getStreet().equals("street"));
        Assert.assertTrue(o.getNumber() == 10);
        System.out.println(o);
    }

    @Test
    public void method2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        MyObjectImpl o = PopulateObjects2.retrieveWithValues(exampleRow);
        Assert.assertTrue(o.getName().equals("name"));
        Assert.assertTrue(o.getStreet().equals("street"));
        Assert.assertTrue(o.getNumber() == 10);
        System.out.println(o);
    }
}

Recommondation

我建议使用第二种方法,即不使用反射。但是,您可能有理由希望能够在未修复列的情况下使用反射,并且您将从某些配置或电子表格的标题中检索这些值。


Code

下面的代码/项目可在https://github.com/johanwitters/stackoverflow-dynamicinit获得


我希望这有帮助。

另一答案

对于MyObjectImpl,请参阅answer of @johan-witters。

Solution 1: constructor accepting array

只需创建一个接受带有值的数组的构造函数。您必须列出字段编号和设置之间的所有映射,但您必须在所有解决方案中执行类似的操作。

public MyObjectImpl(String[] values) {
    this.name = values[0];
    this.street = values[1];
    this.number = Integer.valueOf(values[0]);
    // ...
}

Solution 2: define map with mapper function

有点类似于@ johan-witters的解决方案2,但仅使用标准的Java Functional接口和Method引用,使其更紧凑。

public static void main(String[] args) {

    String[] values = { /* data from file */};

    Map<Integer, BiConsumer<MyObjectImpl, String>> mappers = new HashMap<>();
    mappers.put(0, MyObjectImpl::setName);
    mappers.put(1, MyObjectImpl::setStreet);
    mappers.put(2, asInt(MyObjectImpl::setNumber));
    // ...

    MyObjectImpl obj = retrieveWithValues(values, mappers);

}

private static BiConsumer<MyObjectImpl, String> asInt(BiConsumer<MyObjectImpl, Integer> intConsumer) {
    return (obj, i) ->  intConsumer.accept(obj, Integer.valueOf(i));
}

private static MyObjectImpl retrieveWithValues(String[] values, Map<Integer, BiConsumer<MyObjectImpl, String>> mappers) {
    if (values.length != mappers.size()) {
        return null;
    }
    MyObjectImpl obj = new MyObjectImpl();
    for (int i = 0; i < mappers.size(); i++) {
        mappers.get(i).accept(obj, values[i]);
    }
    return obj;
}

以上是关于类的数据成员为数组,怎么样根据键盘输入的数据顺序建立对象?的主要内容,如果未能解决你的问题,请参考以下文章

给定一个数组,数组内容随机,键盘输入一个数据(数字和单字符),查询是不是存在此数据 c语言代码怎么写?

java中怎么声明键盘扫描器?

C语言:键盘输入1创建顺序表,输入2插入数据,输入3查询数据,输入4删除数据.要求顺序表中的数据为结构体类型

设计一个java程序,从键盘输入三个整数,按照从小到大的顺序输出

java 16 -16 键盘输入数据求最大值

请从键盘输入10个数据 ,每轮循环找到数组中最小的那个删除,数组最后只剩一个?