整数与IP地址间的转换
原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
举例:一个ip地址为10.0.3.193
每段数字 相对应的二进制数
10 00001010
0 00000000
3 00000011
193 11000001
组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。
的每段可以看成是一个0-255的整数,需要对IP地址进行校验
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
while ((str = br.readLine()) != null) {
String[] ip = str.split("\\.");
long num = Long.parseLong(br.readLine());
//转10进制
System.out.println(Long.parseLong(ip[0]) << 24 | Long.parseLong(ip[1]) << 16 |
Long.parseLong(ip[2]) << 8 | Long.parseLong(ip[3]));
//转ip地址
StringBuilder sb = new StringBuilder();
sb.append(String.valueOf((num >> 24) & 255)).append(".").append(String.valueOf((num >> 16) & 255))
.append(".").append(String.valueOf((num >> 8) & 255)).append(".").append(String.valueOf(num & 255));
System.out.println(sb.toString());
}
}
}
#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;
void test33(){
string ip;
long num;
while (std::cin >> ip >> num) {
vector<int> vec;
string tmp;
for (long i = 0; i < ip.length(); i++) {
if (ip[i] != '.') {
tmp += ip[i];
}else{
vec.push_back(atoi(tmp.c_str()));
tmp.clear();
}
if (i == (ip.length()-1)){
vec.push_back(atoi(tmp.c_str()));
tmp.clear();
}
}
long ipNum = 0;
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
//std::cout << *it << " ";
ipNum = ipNum * 256 + *it;
}
std::cout << ipNum << "\n";
stack<int> st;
while (num > 0) {
st.push(num % 256);
num /= 256;
}
while (st.size() > 0) {
if (st.size() == 1) {
std::cout << st.top() << "\n" ;
}else
std::cout << st.top() << ".";
st.pop();
}
}
}
int main(int argc, const char * argv[]) {
// insert code here...
test33();
}
判断两个IP是否属于同一个子网
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。
示例:
I P 地址 192.168.0.1
子网掩码 255.255.255.0
转化为二进制进行运算:
I P 地址 11010000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000
AND运算
11000000.10101000.00000000.00000000
转化为十进制后为:
192.168.0.0
I P 地址 192.168.0.254
子网掩码 255.255.255.0
转化为二进制进行运算:
I P 地址 11010000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000
AND运算
11000000.10101000.00000000.00000000
转化为十进制后为:
192.168.0.0
通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,所以这二台计算机可视为是同一子网络。
/*
- 功能: 判断两台计算机IP地址是同一子网络。
- 输入参数: String Mask: 子网掩码,格式:“255.255.255.0”;
-
String ip1: 计算机1的IP地址,格式:“192.168.0.254”;
-
String ip2: 计算机2的IP地址,格式:“192.168.0.1”;
- 返回值: 0:IP1与IP2属于同一子网络; 1:IP地址或子网掩码格式非法; 2:IP1与IP2不属于同一子网络
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @Author erving
* @date 2020/8/20
**/
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String str;
while((str = bufferedReader.readLine()) !=null) {
String[] mask = str.split("\\.");
String[] ip1 = bufferedReader.readLine().split("\\.");
String[] ip2 = bufferedReader.readLine().split("\\.");
int res=0;
for (int i = 0; i<4; i++){
int a = Integer.parseInt(mask[i]);
int b = Integer.parseInt(ip1[i]);
int c = Integer.parseInt(ip2[i]);
if(a<0||a>255 ||b<0 || b>255||c<0||c>255){
res = 1;
break;
}
if((b&a) != (a&c)){
res = 2;
}
}
System.out.println(res);
}
}
}
#include<bits/stdc++.h>
#include<sstream>
using namespace std;
bool IpstrToUnit(string &ip_str, unsigned int& num)
{
//1.将ipstring 中‘.’转化为' '.好进行字符串读取分割
for(char &c:ip_str)
if(c=='.')
c=' ';
//2.将ip按空格进行分割读取
stringstream ss(ip_str);
vector<int> seg;
unsigned int val=0;
while(ss>>val)
seg.push_back(val);
//判断ip是否合法,IP 位数
if(seg.size()!=4)
return false;
//判断ip是否合法,ip值的大小范围
for(int v:seg)
if(v<0 || v>255)
return false;
num=seg[0]<<24 | seg[1]<<16 | seg[2]<<8 |seg[3]<<0;
return true;
}
int main()
{
string mask, ip1, ip2;
while(cin>>mask>>ip1>>ip2)
{
unsigned int mask_num,num1,num2;
if(IpstrToUnit(mask,mask_num) && IpstrToUnit(ip1,num1) && IpstrToUnit(ip2,num2))
{
if((mask_num & num1)==(mask_num & num2))
cout<<"0"<<endl;
else
cout<<"2"<<endl;
}
else
cout<<"1"<<endl;
}
return 0;
}
称砝码
现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
每种砝码对应的数量为x1,x2,x3…xn。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
注:
称重重量包括0
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/*
* 现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
每种砝码对应的数量为x1,x2,x3...xn。
现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
注:
称重重量包括0
方法原型:public static int fama(int n, int[] weight, int[] nums)
*/
public class Main {
public static void main(String[] args) throws NumberFormatException, IOException {
// 1.高效读数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String mark = null;
while ((mark = br.readLine()) != null) {
int n = Integer.parseInt(mark);
String[] s1 = br.readLine().split(" ");
String[] s2 = br.readLine().split(" ");
int[] weight = new int[s1.length];
int[] nums = new int[s2.length];
for (int i = 0; i < n; i++) {
weight[i] = Integer.parseInt(s1[i]);
nums[i] = Integer.parseInt(s2[i]);
}
System.out.println(fama(n, weight, nums));
}
}
public static int fama(int n, int[] weight, int[] nums){
int sum = 0;
for(int i =0;i<n;i++){
sum = sum + nums[i]* weight[i];
}
boolean[] weg = new boolean[sum+1];
weg[0] =true;
weg[sum] = true;
// 三重循环,分别表示 n个砝码,weight.length 个种类,每个种类有 num.length 个数量
for(int i =0; i< n; i++){
for (int j = 0; j < nums[i]; j++) {
for(int k=sum; k>= weight[i];k--){
// weg[k-weight[i]]== true,意思就是 k-weight[i] + weight[i] == k,可以称出 k 重量
if(weg[k -weight[i] ]){
weg[k] = true;
}
}
}
}
int count = 0;
for (boolean b : weg) {
if (b) count++;
}
return count;
}
}
#include <iostream>
using namespace std;
int main(){
int n;
while(cin>>n){
int w[10]={0}; int num[10]={0};
for(int i=0;i<n;i++)
cin>>w[i];
for(int i=0;i<n;i++)
cin>>num[i];
int v[12000]={0}; int maxw=0;
for(int i=0;i<n;i++)
maxw+=num[i]*w[i];
v[0]=1;
//类似背包问题
for(int i=0;i<n;i++) //砝码类别
for(int j=maxw;j>=0;j--) //背包容量
for(int k=1;k<=num[i];k++){ //砝码数量
if(v[j]==1 && j+k*w[i]<=maxw)
v[j+k*w[i]]=1;
}
int res=0;
for(int i=0;i<=maxw;i++)
if(v[i]==1)
res++;
cout<<res<<endl;
}
return 0;
}