5.23 学习总结

一.项目优化(语音通话)

实现步骤:

1.用户发送通话申请,并处理通话请求,如果同意,为两个用户之间进行连接。

2.获取到电脑的麦克风和扬声器,将获取到的语音信息转换成以字节数组的形式传递。

3.通过流循环的传递和接收字节数组,保持一个持续的语音通话。

4.另开一个线程当做计时器和结束聊天的作用。

实现代码:

1.获取电脑麦克风,将语音信息转换为字节数组,进行传递的方法(因为要保持通话,所以要循环的去发送字节数组,如果要中断聊天可以使用stop方法,来跳出循环;同时为了快速通畅的通讯,用1kb的数组去传递)

复制代码
public void run() {

        try {
            captrueOutputStream=new BufferedOutputStream(s.getOutputStream());//建立输出流 此处可以加套压缩流用来压缩数据
        }
        catch (IOException ex) {
            return;
        }

        AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
        DataLine.Info info = new DataLine.Info(TargetDataLine.class,format);

        try {
            line = (TargetDataLine) AudioSystem.getLine(info);
            line.open(format, line.getBufferSize());
        } catch (Exception ex) {
            return;
        }

        byte[] data = new byte[1024];//此处的1024可以情况进行调整,应跟下面的1024应保持一致
        int numBytesRead=0;
        line.start();

        while (thread != null) {
            numBytesRead = line.read(data, 0,1024);//取数据(1024)的大小直接关系到传输的速度,一般越小越快,
            try {
                captrueOutputStream.write(data, 0, numBytesRead);//写入网络流
            }
            catch (Exception ex) {
                break;
            }
        }

        line.stop();
        line.close();
        line = null;

        try {
            captrueOutputStream.flush();
            captrueOutputStream.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

2.获取电脑扬声器,接收传递来的字节数组,再转换为音频,通过扬声器播放。(接收与发送的类似,不过多赘述)

复制代码
public void run() {

        AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
        BufferedInputStream playbackInputStream;

        try {
            playbackInputStream=new BufferedInputStream(new AudioInputStream(s.getInputStream(),format,2147483647));//封装成音频输出流,如果网络流是经过压缩的需在此加套解压流
        }
        catch (IOException ex) {
            return;
        }

        DataLine.Info info = new DataLine.Info(SourceDataLine.class,format);

        try {
            line = (SourceDataLine) AudioSystem.getLine(info);
            line.open(format, bufSize);
        } catch (LineUnavailableException ex) {
            return;
        }

        byte[] data = new byte[1024];//此处数组的大小跟实时性关系不大,可根据情况进行调整
        int numBytesRead = 0;
        line.start();

        while (thread != null) {
            try{
                numBytesRead = playbackInputStream.read(data);
                line.write(data, 0,numBytesRead);
            } catch (IOException e) {
                break;
            }
        }

        if (thread != null) {
            line.drain();
        }

        line.stop();
        line.close();
        line = null;
    }

3.开启计时线程,监听语音聊天过程,添加结束聊天的按钮,中断循环。

复制代码
private void openCallWindow1(Playback playback) {
        Stage callStage = new Stage();
        callStage.setTitle("通话中");

        BorderPane callRoot = new BorderPane();

        // 创建计时器标签
        Label timerLabel = new Label("00:00:00");
        timerLabel.setStyle("-fx-font-size: 24");
        callRoot.setCenter(timerLabel);

        // 创建关闭按钮
        Button closeButton = new Button("结束通话");
        closeButton.setOnAction(e -> {
            callStage.close();
            playback.stop();
        });
        callRoot.setBottom(closeButton);

        // 创建计时器线程
        Thread timerThread = new Thread(() -> {
            int hours = 0, minutes = 0, seconds = 0;
            while (true) {
                try {
                    // 更新计时器标签
                    String time = String.format("%02d:%02d:%02d", hours, minutes, seconds);
                    Platform.runLater(() -> timerLabel.setText(time));
                    Thread.sleep(1000); // 休眠一秒钟
                    seconds++;
                    if (seconds == 60) {
                        seconds = 0;
                        minutes++;
                    }
                    if (minutes == 60) {
                        minutes = 0;
                        hours++;
                    }
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        });
        timerThread.setDaemon(true); // 设置为守护线程,以确保程序退出时结束计时器线程
        timerThread.start(); // 启动计时器线程

        Scene scene = new Scene(callRoot, 300, 200);
        callStage.setScene(scene);
        callStage.show();
    }

效果展示:

二.算法练题

Codeforces Round 946 (Div. 3) D. Ingenuity-2

解题思路:

本题是一到模拟题,按照题目的要求来进行模拟即可,首先从题意我们可以得出以下几点:

1.在竖直或者水平方向(即x或者y方向上)的累计,只能是偶数,如果是奇数即输出 NO。

2.当只要两步时,x和y不可能为0,或者x和y不一样。

3.我们可以通过对x和y的值计算来得出H和R的行动,并且如果要保持一致,每一次的行动都应该是以2为单位进行。

复制代码
#include<bits/stdc++.h>
using namespace std;
#define N 200005
int n, m, t;
int main()
{
	cin >> t;
	while (t--)
	{
		string s, ss;
		int x=0, y=0;
		cin >> n;
		cin >> s;
        //计算x和y值
		for (int i = 0; i < n; i++) {
			if (s[i] == 'N') y += 1;
			if (s[i] == 'S') y -= 1;
			if (s[i] == 'E') x += 1;
			if (s[i] == 'W') x -= 1;
		}
        //假设一开始都是R行动
		for (int i = 0; i < n; i++) {
			ss += 'R';
		}
		if (x % 2 != 0 || y % 2 != 0) {
			cout << "NO" << endl;
			continue;
		}
		else if (x == 0 && y == 0) {
			if (n == 2) {
				cout << "NO" << endl;
				continue;
			}
            //如果要保持不动,一定会出现相反方向的行动
			else {
				if (s[0] == 'N') {
					ss[0] = ss[s.find('S')] = 'H';
				}
				if (s[0] == 'S') {
					ss[0] = ss[s.find('N')] = 'H';
				}
				if (s[0] == 'W') {
					ss[0] = ss[s.find('E')] = 'H';
				}
				if (s[0] == 'E') {
					ss[0] = ss[s.find('W')] = 'H';
				}
			}
		}
		else
		{   //通过x和y值去模拟一种可能
			for (int i = 0; i < n; i++) {
				if (s[i] == 'N' && y>0)
					ss[i] = 'H', y -= 2;
				if (s[i] == 'S' && y<0)
					ss[i] = 'H', y += 2;
				if (s[i] == 'W' && x<0)
					ss[i] = 'H', x += 2;
				if (s[i] == 'E' && x>0)
					ss[i] = 'H', x -= 2;
			}
		}
		cout << ss << endl;
	}
	return 0;
}
相关推荐
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码7 天前
嵌入式学习路线
学习
毛小茛7 天前
计算机系统概论——校验码
学习
babe小鑫7 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms7 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下7 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。7 天前
2026.2.25监控学习
学习
im_AMBER7 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J7 天前
从“Hello World“ 开始 C++
c语言·c++·学习