Tutorial: 415. Add String

题目

给定两个数对应的字符串,要求返回两数之和所对应的字符串。这两个数最大长度<5100。

算法

由题目所得,由于数字的长度超过了double所能支持的最大长度,所以我们不能通过系统内置的数字类型来对这两个数求和。
我们所要做的就是像我们自己手工计算一样,把这两个数一位一位地做加法,处理好进位就行。就可以提出以下算法:
1. 判定这两个数哪一个比较长一点,给长一点的数在前面补零,是两个数长度对齐
2. 新建一个StringBuilder类型变量stringBuilder,和int类型的变量sum,carry
3. 令sum,carry为0
4. 从低位到高位,一位一位地计算两者之和。这里,可以把该位的字符-48来的到对应的数字,用于后续计算。如有进位,则置carry为0。把sum转成字符append到stringBuilder里面。
5. 重复操作直至两个数中的所有位均为计算
6. 判定carry是否为1,若true,则在stringBuilder中append一个1
7. 把这个StringBuilder反过来输出(stringBuilder.reverse().toString())

代码

//主算法
private String addStrings(String num1, String num2) {
    int carry=0;
    int sum=0;
    StringBuilder stringBuilder=new StringBuilder();
    if (num1.length()>num2.length()){
        num2=AddZero(num2,num1.length()-num2.length());
    }else {
        num1=AddZero(num1,num2.length()-num1.length());
    }
    for(int i=num1.length()-1;i>=0;i--){
        sum=(num1.charAt(i)-48)+(num2.charAt(i)-48)+carry;
        if (sum>9){
            stringBuilder.append(sum-10);
            carry=1;
        }else {
            stringBuilder.append(sum);
            carry=0;
        }
    }
    if (carry==1){
        stringBuilder.append(1);
    }
    return stringBuilder.reverse().toString();
}

//通过补0来对齐两个数
private String AddZero(String s,int count){
    StringBuilder stringBuilder=new StringBuilder();
    for(int i=0;i<count;i++){
        stringBuilder.append("0");
    }
    stringBuilder.append(s);
    return stringBuilder.toString();
}

关于此文章

本文首发于作者的个人博客stormlin.com。你也扫描以下二维码来关注我的个人微信公众号来获取更多更新鲜的内容哦。
QR Code

<think>我们正在创建一个ROS包,用于两台计算机在同一局域网中的通信。其中一台(A机)发布系统时间,另一台(B机)接收并打印数据。同时,我们需要创建自定义消息类型(虽然系统时间可以使用标准消息,但为了练习,我们创建自定义消息)。步骤:1.创建ROS包和工作空间(如果已有工作空间,则跳过创建工作空间)2.创建自定义消息类型(这里我们创建一个包含系统时间的消息)3.编写发布者节点(A机)4.编写订阅者节点(B机)5.配置网络和ROS环境,确保两台计算机在同一网络且ROS可以通信(设置ROS_MASTER_URI和ROS_HOSTNAME/IP)6.运行测试注意:由于是两台计算机,我们需要确保它们使用相同的ROS_MASTER(通常设置其中一台为master),并且网络配置正确(互相可以ping通,且端口开放)。详细步骤:1.创建工作空间和包假设我们已经在两台计算机上安装了ROS(这里以Melodic或Noetic为例)。在A机(或B机,我们选择其中一台作为开发机,然后复制到另一台,或者分别在两台机器上创建):```mkdir-p~/custom_msg_ws/srccd~/custom_msg_ws/srccatkin_init_workspace```创建包,包依赖于message_generation和message_runtime(用于自定义消息)以及roscpp、std_msgs(用于C++节点):```catkin_create_pkgcustom_msg_tutorial roscppstd_msgsmessage_generation message_runtime```2.创建自定义消息在包中创建msg目录,并在其中定义消息文件。```cdcustom_msg_tutorialmkdirmsgecho"timesystem_time"> msg/SystemTime.msg```注意:这里我们定义了一个消息,只有一个字段`system_time`,类型是`time`(ROS内置的时间类型)。修改package.xml,确保有以下两行(通常catkin_create_pkg已经添加了依赖,但需要检查):```xml<build_depend>message_generation</build_depend><exec_depend>message_runtime</exec_depend>```修改CMakeLists.txt:-在`find_package`中添加`message_generation`:```cmakefind_package(catkin REQUIRED COMPONENTSroscppstd_msgsmessage_generation)```-添加消息定义:```cmakeadd_message_files(FILESSystemTime.msg)```-确保生成消息的依赖被正确设置:```cmakegenerate_messages(DEPENDENCIESstd_msgs)```-在`catkin_package`中添加`message_runtime`:```cmakecatkin_package(CATKIN_DEPENDS message_runtimeroscpp std_msgs)```3.编写发布者节点(A机)在包中创建src目录,然后创建publisher.cpp:```cpp#include "ros/ros.h"#include"custom_msg_tutorial/SystemTime.h"intmain(intargc,char **argv){ros::init(argc, argv, "time_publisher");ros::NodeHandle nh;ros::Publisher pub= nh.advertise<custom_msg_tutorial::SystemTime>("system_time",10);ros::Raterate(1);//1Hzwhile (ros::ok()){custom_msg_tutorial::SystemTimemsg;msg.system_time= ros::Time::now();pub.publish(msg);ROS_INFO("Publishing time: %f",msg.system_time.toSec());rate.sleep();}return0;}```4.编写订阅者节点(B机)同样在src目录下创建subscriber.cpp:```cpp#include"ros/ros.h"#include "custom_msg_tutorial/SystemTime.h"void timeCallback(constcustom_msg_tutorial::SystemTime::ConstPtr& msg){ROS_INFO("Receivedtime: %f",msg->system_time.toSec());}int main(int argc, char**argv){ros::init(argc,argv,"time_subscriber");ros::NodeHandlenh;ros::Subscriber sub= nh.subscribe("system_time",10, timeCallback);ros::spin();return0;}```5.修改CMakeLists.txt以构建节点在CMakeLists.txt末尾添加:```cmakeinclude_directories(${catkin_INCLUDE_DIRS})add_executable(time_publishersrc/publisher.cpp)target_link_libraries(time_publisher ${catkin_LIBRARIES})add_dependencies(time_publisher custom_msg_tutorial_generate_messages_cpp)add_executable(time_subscriber src/subscriber.cpp)target_link_libraries(time_subscriber${catkin_LIBRARIES})add_dependencies(time_subscribercustom_msg_tutorial_generate_messages_cpp)```6.构建工作空间```cd ~/custom_msg_wscatkin_makesourcedevel/setup.bash```7.网络配置假设两台计算机在同一局域网,且可以互相ping通。选择一台作为ROSmaster(假设选择A机作为master):在A机上:-设置ROS_MASTER_URI为自身IP(假设A机IP为192.168.1.100):`exportROS_MASTER_URI=http://192.168.1.100:11311`-设置ROS_HOSTNAME(或ROS_IP)为A机的IP:`export ROS_HOSTNAME=192.168.1.100`在B机上:-设置ROS_MASTER_URI为A机的IP:`exportROS_MASTER_URI=http://192.168.1.100:11311`-设置ROS_HOSTNAME(或ROS_IP)为B机的IP(假设192.168.1.101):`exportROS_HOSTNAME=192.168.1.101`注意:这些设置可以写入~/.bashrc,以便每次启动终端自动设置。8.运行在A机(master)上:```roscore```然后运行发布者节点(在A机上):```rosrun custom_msg_tutorial time_publisher```在B机上:```rosrun custom_msg_tutorial time_subscriber```此时,B机应该会每秒打印一次从A机接收到的系统时间。注意:如果使用不同的ROS版本,步骤可能略有不同,但整体流程一致。相关问题:1.如何确保两台计算机在同一ROS网络中?2.自定义消息类型时需要注意哪些问题?3.如果通信出现延迟,可能的原因和排查方法是什么?4.如何将自定义消息类型用于Python节点?</think>### ROS自定义消息类型与跨机通信实现 以下是创建ROS包、自定义消息类型并实现两台计算机通信的完整步骤: #### 1. 创建ROS包和自定义消息 ```bash # 创建工作空间 mkdir -p ~/custom_msg_ws/src cd ~/custom_msg_ws/src # 创建包含自定义消息的包 catkin_create_pkg custom_time_msgs rospy std_msgs message_generation # 创建消息目录 cd custom_time_msgs mkdir msg ``` 在`msg/SystemTime.msg`文件中定义消息: ```text time stamp string hostname ``` #### 2. 配置包依赖 修改`package.xml`: ```xml <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend> ``` 修改`CMakeLists.txt`: ```cmake find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation ) add_message_files( FILES SystemTime.msg ) generate_messages( DEPENDENCIES std_msgs ) catkin_package( CATKIN_DEPENDS message_runtime roscpp rospy std_msgs ) ``` #### 3. 构建消息 ```bash cd ~/custom_msg_ws catkin_make source devel/setup.bash ``` #### 4. 实现发布者节点(A机) 在`custom_time_msgs/scripts/time_publisher.py`中: ```python #!/usr/bin/env python import rospy from custom_time_msgs.msg import SystemTime import socket def publisher(): rospy.init_node('time_publisher') pub = rospy.Publisher('system_time', SystemTime, queue_size=10) rate = rospy.Rate(1) # 1Hz hostname = socket.gethostname() while not rospy.is_shutdown(): msg = SystemTime() msg.stamp = rospy.Time.now() msg.hostname = hostname pub.publish(msg) rospy.loginfo(f"Published: {msg.stamp.to_sec()} from {hostname}") rate.sleep() if __name__ == '__main__': try: publisher() except rospy.ROSInterruptException: pass ``` #### 5. 实现订阅者节点(B机) 在`custom_time_msgs/scripts/time_subscriber.py`中: ```python #!/usr/bin/env python import rospy from custom_time_msgs.msg import SystemTime def callback(msg): recv_time = rospy.Time.now() latency = (recv_time - msg.stamp).to_sec() rospy.loginfo(f"Received: {msg.stamp.to_sec()} from {msg.hostname} | Latency: {latency:.6f}s") def subscriber(): rospy.init_node('time_subscriber') rospy.Subscriber('system_time', SystemTime, callback) rospy.spin() if __name__ == '__main__': subscriber() ``` #### 6. 网络配置关键步骤 1. **确保两台计算机在同一局域网**: ```bash # 在两台机器上互相ping ping <对方IP> ``` 2. **设置主机名解析**: 在`/etc/hosts`中添加对方IP和主机名: ```text 192.168.1.100 robot-pc 192.168.1.101 control-pc ``` 3. **配置ROS环境变量**: 在A机(发布者): ```bash echo "export ROS_MASTER_URI=http://$(hostname):11311" >> ~/.bashrc echo "export ROS_HOSTNAME=$(hostname)" >> ~/.bashrc ``` 在B机(订阅者): ```bash echo "export ROS_MASTER_URI=http://<A机IP>:11311" >> ~/.bashrc # 指向A机 echo "export ROS_HOSTNAME=$(hostname)" >> ~/.bashrc ``` 4. **验证通信**: ```bash # A机 roscore rosrun custom_time_msgs time_publisher.py # B机 rosrun custom_time_msgs time_subscriber.py ``` #### 7. 通信优化建议 1. **使用DDS域ID隔离网络**(当存在多个ROS组时)[^3]: ```bash # 所有机器使用相同域ID export ROS_DOMAIN_ID=42 ``` 2. **提高通信效率**: - 使用ZeroMQ替代默认通信层[^1] - 调整TCP缓冲区大小: ```bash sudo sysctl -w net.core.rmem_max=2097152 sudo sysctl -w net.core.wmem_max=2097152 ``` 3. **验证网络质量**: ```bash # 测量节点间延迟 rostopic hz /system_time rostopic bw /system_time ``` ### 常见问题排查 1. **无法接收消息**: - 检查防火墙设置:`sudo ufw allow 11311/tcp` - 验证环境变量:`echo $ROS_MASTER_URI` - 使用`rostopic list`查看可用话题 2. **消息延迟过高**: - 减少消息大小(避免发送大图像等) - 使用`rosparam set /use_sim_time true`同步时间 - 检查网络带宽:`iperf3 -c <对方IP>` 3. **自定义消息未识别**: - 确保所有机器`source devel/setup.bash` - 重新构建消息:`catkin_make --force-cmake` > **注意**:在实际无人机集群或机器人系统中,可结合B.A.T.M.A.N.协议实现分布式组网[^1],或采用"PC+嵌入式系统"架构[^2]优化通信性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值