RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题

全部问题

Martin Hope
Qwer
Asked: 2024-01-02 00:34:38 +0000 UTC

字符串的逻辑运算符

  • 9

有一段代码:

String a = "Hello", b = "Hello";
System.out.println("a==b: " + a==b);
System.out.println("a!=b: " + a!=b);

其输出以下值:

false
true

我知道运算符==比较!=引用,因此输出结果 (false, true),但我不明白字符串值从 string 到"a==b: "哪里"a!=b: "。我认为这里与类型转换有关,但我无法完全理解它。有人可以更具体地解释一下吗?

java
  • 2 个回答
  • 55 Views
Martin Hope
Никита
Asked: 2023-12-29 22:13:48 +0000 UTC

正确的运算符重载 [] (C++)

  • 9

我面临着编写自己的关联数组并为其重载索引运算符 [] 的任务。我写的,重载看起来像这样:

template<class Key, class Data>
Data& AssociativeArray<Key, Data>::operator[](const Key& key)
{
    for (Pair& p : array)
    {
        if (p.key == key)
        {
            return p.value;
        }
    }

    // Если ключ не найден создаём новую пару
    Pair newPair = { key, Data{} };
    array.push_back(newPair);
    return array.back().value;
}

//для константного массива
template<class Key, class Data>
const Data& AssociativeArray<Key, Data>::operator[](const Key& key) const
{
    for (const Pair& p : array)
    {
        if (p.key == key)
        {
            return p.value;
        }
    }
    return Data{};
}

我认为我的问题已经很明显了:在我的实现中,我寻找一个键,如果它不存在,我用这样的键创建一个新的空元素。一方面,这很方便 - 这样我可以分配一个新值,就像常规数组一样:

Arr["newKey"] = "new value";

但另一方面,当尝试从不存在的键中获取值时

std::string str = Arr["newKey"];

它创建一个新的空的,虽然它不应该,但应该抛出一个错误。

所以问题是:我怎样才能正确地做到这一点,以便它在接收值时抛出错误,并在添加它时创建一个元素?

以防万一,这是整个类结构:

template<class Key, class Data>
class AssociativeArray
{
public:
    Data& operator[](const Key& key);
    const Data& operator[](const Key& key) const;
    template<class K, class D>
    friend std::ostream& operator<<(std::ostream& os, const AssociativeArray<K, D>& arr);

private:
    struct Pair
    {
        Key key;
        Data value;
    };
    std::vector<Pair> array;
};

template<class Key, class Data>
Data& AssociativeArray<Key, Data>::operator[](const Key& key)
{
    for (Pair& p : array)
    {
        if (p.key == key)
        {
            return p.value;
        }
    }

    // Если ключ не найден создаём новую пару
    Pair newPair = { key, Data{} };
    array.push_back(newPair);
    return array.back().value;
}

template<class Key, class Data>
const Data& AssociativeArray<Key, Data>::operator[](const Key& key) const
{
    for (const Pair& p : array)
    {
        if (p.key == key)
        {
            return p.value;
        }
    }
    return Data{};
}

template<class Key, class Data>
std::ostream& operator<<(std::ostream& os, const AssociativeArray<Key, Data>& arr)
{
    for (const auto& pair : arr.array)
    {
        os << "Key: " << pair.key << ", Value: " << pair.value << std::endl;
    }
    return os;
}
c++
  • 2 个回答
  • 83 Views
Martin Hope
Alexey Trukhanov
Asked: 2023-12-21 19:34:06 +0000 UTC

如何在不多次调用函数的情况下实现列表包含

  • 9

同事们,免责声明。有一个问题,从实现的角度来看,我想出了一个抽象且完全愚蠢的例子。这个例子只是为了说明我的问题,并不是一个好的解决方案的例子。

这是一个例子:

import random

random.seed(123)

def test_random(len):
    return [random.randint(0, 10) ** 2 for _ in range(len)]

print ([test_random(10)[i] for i in range(3)])

有一个函数可以生成并返回某个集合,可以通过索引/键来访问该集合的元素。列表、字典、元组 - 没关系,在示例中,为了便于说明,我使用了列表。给定相同的输入数据,该函数返回相同的结果。我们使用列表/字典包含,尝试根据此函数返回的集合生成一些其他集合。问题很明显 - 通过这种实现,我们每次迭代列表包含时都请求该函数,而不是一次获取对象并访问它。

问题。

是否可以在不多次调用函数并且不首先引入一个临时变量(我将在其中返回函数结果)的情况下实现这样的逻辑?

python
  • 3 个回答
  • 88 Views
Martin Hope
Dimka4369
Asked: 2023-12-11 01:43:52 +0000 UTC

为什么立方体绘制不正确?

  • 9

我正在尝试用 C++ 绘制一个立方体,但它看起来不太像我想要的那样。我正在使用公式将球坐标转换为笛卡尔(直角)坐标。这个想法是找到光线从窗口的每个像素照射到的位置。如果光线击中物体,则绘制该像素。

以下是代码的主要部分:

int Screen[320 * 180 * 3] = { 0 };
int World[160][90][90] = { 0 };
int X1 = 0;
int Y1 = 0;
int BasicAngle = 0;

    World[10][10][0] = 1;
    World[10][10][10] = 1;
    World[20][20][20] = 1;
    World[40][40][40] = 1;
    World[40][20][10] = 1;

    createWindow(0, 0, 320, 180);

        for (int y = 0; y < 90; y++)
        {
            double B = (90.0 / 90.0) * y;
            for (int x = 0; x < 160; x++)
            {
                double A = (90.0 / 160.0) * x + BasicAngle;
                for (int R = 0; R < 100; R++)
                {
                    int X = X1 + R * sin(B * M_PI / 180) * cos(A * M_PI / 180);
                    int Y = Y1 + R * sin(B * M_PI / 180) * sin(A * M_PI / 180);
                    int Z = R * cos(B * M_PI / 180);

                    if (X < 160 && Y < 90 && X > -1 && Y > -1 && Z > -1 && Z < 90)
                    {
                        if (World[X][Y][Z] == 1)
                        {
                            R = 100;

                            Screen[y * 320 * 3 + (x + 160) * 3 + 0] = 255; // red правый
                            Screen[y * 320 * 3 + (x + 160) * 3 + 1] = 0; // green правый
                            Screen[y * 320 * 3 + (x + 160) * 3 + 2] = 0; // blue правый



                            Screen[Y * 320 * 3 + X * 3 + 0] = 255; // red левый
                            Screen[Y * 320 * 3 + X * 3 + 1] = 0; // green левый
                            Screen[Y * 320 * 3 + X * 3 + 2] = 0; // blue левый
                        }
                        else
                        {
                            Screen[Y * 320 * 3 + X * 3 + 0] = 0; // red левый
                            Screen[Y * 320 * 3 + X * 3 + 1] = 255; // green левый
                            Screen[Y * 320 * 3 + X * 3 + 2] = 0; // blue левый
                        }
                    }
                }
            }
        }

是什么导致了这种扭曲?如果有其他方法来发射光束,我可能会考虑这种可能性。也许问题在于确定射线和物体的交点?我想以体素的形式存储对象,然后从立方体中组装一些有趣的东西,而不是多边形。

添加。

按空格键时将截取屏幕截图。

#include <Windows.h>
#include <iostream>
#include <fstream>
#include <cmath>
double M_PI = 3.1415926535;

void save1dArrayToBMP(const char* path, int* buffer, int width, int height)
{
    std::ofstream file;
    file.open(path, std::ios::out | std::ios::binary);

    unsigned char bmpPadding[3] = { 0, 0, 0 };
    const int paddingAmount = (4 - (width * 3) % 4) % 4;

    const int fileHeaderSize = 14;
    const int informationHeaderSize = 40;
    const int fileSize = fileHeaderSize + informationHeaderSize + width * height * 4;

    unsigned char fileHeader[fileHeaderSize];

    //File type
    fileHeader[0] = 'B';
    fileHeader[1] = 'M';
    // File size
    fileHeader[2] = fileSize;
    fileHeader[3] = fileSize >> 8;
    fileHeader[4] = fileSize >> 16;
    fileHeader[5] = fileSize >> 24;
    //Reserved 1 (not used)
    fileHeader[6] = 0;
    fileHeader[7] = 0;
    //Reserved 2 (not used)
    fileHeader[8] = 0;
    fileHeader[9] = 0;
    //Pixel data offset
    fileHeader[10] = fileHeaderSize + informationHeaderSize;
    fileHeader[11] = 0;
    fileHeader[12] = 0;
    fileHeader[13] = 0;

    unsigned char informationHeader[informationHeaderSize];

    //Header size
    informationHeader[0] = informationHeaderSize;
    informationHeader[1] = 0;
    informationHeader[2] = 0;
    informationHeader[3] = 0;
    //Image width
    informationHeader[4] = width;
    informationHeader[5] = width >> 8;
    informationHeader[6] = width >> 16;
    informationHeader[7] = width >> 24;
    //Image height
    informationHeader[8] = height;
    informationHeader[9] = height >> 8;
    informationHeader[10] = height >> 16;
    informationHeader[11] = height >> 24;
    //Planes
    informationHeader[12] = 1;
    informationHeader[13] = 0;
    //Bits per pixels (RGB)
    informationHeader[14] = 24;
    informationHeader[15] = 0;
    //Compression (no compression)
    informationHeader[16] = 0;
    informationHeader[17] = 0;
    informationHeader[18] = 0;
    informationHeader[19] = 0;
    //Image size (no compression)
    informationHeader[20] = 0;
    informationHeader[21] = 0;
    informationHeader[22] = 0;
    informationHeader[23] = 0;
    //X pixels per meter (not specified)
    informationHeader[24] = 0;
    informationHeader[25] = 0;
    informationHeader[26] = 0;
    informationHeader[27] = 0;
    //Y pixels per meter (not specified)
    informationHeader[28] = 0;
    informationHeader[29] = 0;
    informationHeader[30] = 0;
    informationHeader[31] = 0;
    //Total colors (colors palette not used)
    informationHeader[32] = 0;
    informationHeader[33] = 0;
    informationHeader[34] = 0;
    informationHeader[35] = 0;
    //Important colors (Generally ignored)
    informationHeader[36] = 0;
    informationHeader[37] = 0;
    informationHeader[38] = 0;
    informationHeader[39] = 0;

    file.write(reinterpret_cast<char*>(fileHeader), fileHeaderSize);
    file.write(reinterpret_cast<char*>(informationHeader), informationHeaderSize);
    //file.write(reinterpret_cast<char*>(buffer), width * height * 4);

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            unsigned char r = static_cast<unsigned char>(buffer[(height - y - 1) * width * 3 + x * 3 + 0]);
            unsigned char g = static_cast<unsigned char>(buffer[(height - y - 1) * width * 3 + x * 3 + 1]);
            unsigned char b = static_cast<unsigned char>(buffer[(height - y - 1) * width * 3 + x * 3 + 2]);

            unsigned char color[] = { b, g, r };


            file.write(reinterpret_cast<char*>(color), 3);
        }
        file.write(reinterpret_cast<char*>(bmpPadding), paddingAmount);
    }

    file.close();

    std::cout << "File created\n";
}

int World[160][90][90] = { 0 };
int X1 = 0;
int Y1 = 0;
int BasicAngle = 0;
int Screen[320 * 180 * 3] = { 0 };

void drawLine(int x1, int y1, int z1, int x2, int y2, int z2, int ScreenX, int ScreenY) {
    int dx = x2 - x1;
    int dy = y2 - y1;
    int dz = z2 - z1;

    int steps = max(max(abs(dx), abs(dy)), abs(dz));  // Выбираем максимальное изменение по координатам как количество шагов

    int xInc = dx / steps;
    int yInc = dy / steps;
    int zInc = dz / steps;

    int x = x1;
    int y = y1;
    int z = z1;

    for (int i = 0; i <= steps; i++) {

        if (x < 160 && y < 90 && x > -1 && y > -1 && z > -1 && z < 90)
        {
            if (World[x][y][z] == 1)
            {
                i = steps;

                Screen[ScreenY * 320 * 3 + (ScreenX + 160) * 3 + 0] = 255; // red
                Screen[ScreenY * 320 * 3 + (ScreenX + 160) * 3 + 1] = 0; // green
                Screen[ScreenY * 320 * 3 + (ScreenX + 160) * 3 + 2] = 0; // blue

                Screen[y * 320 * 3 + x * 3 + 0] = 255; // red
                Screen[y * 320 * 3 + x * 3 + 1] = 0; // green
                Screen[y * 320 * 3 + x * 3 + 2] = 0; // blue
            }
            else
            {
                Screen[y * 320 * 3 + x * 3 + 0] = 0; // red
                Screen[y * 320 * 3 + x * 3 + 1] = 255; // green
                Screen[y * 320 * 3 + x * 3 + 2] = 0; // blue
            }
        }
        x += xInc;
        y += yInc;
        z += zInc;
    }
}

int main()
{
    World[10][10][0] = 1;
    World[10][10][10] = 1;
    World[20][20][20] = 1;
    World[40][40][40] = 1;
    World[40][20][10] = 1;
    while (true)
    {
        for (int i = 0; i < 320 * 180 * 3; i++)
        {
            Screen[i] = 0;
        }
        for (int x = 0; x < 320; x++)
        {
            Screen[90 * 320 * 3 + x * 3 + 0] = 255; // red
            Screen[90 * 320 * 3 + x * 3 + 1] = 255; // green
            Screen[90 * 320 * 3 + x * 3 + 2] = 255; // blue
        }
        for (int y = 0; y < 180; y++)
        {
            Screen[y * 320 * 3 + 160 * 3 + 0] = 255; // red
            Screen[y * 320 * 3 + 160 * 3 + 1] = 255; // green
            Screen[y * 320 * 3 + 160 * 3 + 2] = 255; // blue
        }
        for (int y = 0; y < 90; y++)
        {
            double B = (90.0 / 90.0) * y;
            for (int x = 0; x < 160; x++)
            {
                double A = (90.0 / 160.0) * x + BasicAngle;

                int R = 100;
                int X = X1 + R * sin(B * M_PI / 180) * cos(A * M_PI / 180);
                int Y = Y1 + R * sin(B * M_PI / 180) * sin(A * M_PI / 180);
                int Z = R * cos(B * M_PI / 180);

                drawLine(X1, Y1, 0, X, Y, Z, x, y);
            }
        }
        if (GetAsyncKeyState(VK_SPACE))
        {
            save1dArrayToBMP("Frame.bmp", Screen, 320, 180);
            Sleep(100);
        }
    }
}

12/23/2023:我们通过三角形的相似性取得了一些结果。到目前为止我只在 2D 中尝试过。它看起来像这样:

添加了 Bresenham 算法:

使用该算法的面积仅减少。视角会影响中心光线的分组,但我不能无限地减小角度(增加焦距、腿)。你能为这个做什么?(没有算法的代码)

int Focus = 32;
for (int x = -15; x < 16; x++)
{
    double L = sqrt(Focus * Focus + x * x);
    for (double Lenght = 0; Lenght < 100; Lenght += 0.1)
    {
        double coeff = Lenght / L;
        int X = x * coeff;
        int Y = Focus * coeff;

        Screen[Y * 320 * 3 + (X + 160) * 3 + 1] = 255;
    }
}

这里的代码中有从-15到16,因此有空,但是从-159到160是必要的。我弄清楚了并切换到3D

只需 1 行即可转换为 3D:

double L = sqrt(Focus * Focus + x * x + y * y);

一个非常好的结果,我不喜欢的是立方体的波纹度,不均匀的边缘。

我无法在 3D 中添加 Bresenham 算法,我不明白为什么。但该步骤提高了清晰度,但性能却显着下降。现在步长是0.01,但我想要0.5

我无法理解以下内容:

  1. 为什么布雷森纳姆算法不起作用?
  2. 如果我需要获得坐标而不是矩阵,如何将坐标乘以矩阵(以旋转相机)?
  3. Как можно обойти искажение без шага? Очень сильно упала производительность.

30.12.23 Последние результаты такие, для разрешения 640х480 дальность прорисовки от 130 до примерно 150 единиц, слева направо:

  1. 8.323 с. (метод на подобии треугольников, шаг: 0.01)
  2. 9.648 с. (метод по уравнению прямой, шаг на умножении: 0.00001)
  3. 6.824 с. (метод по уравнению прямой, шаг на сложении: 0.00001)
  4. 0.479 с. (код Станислава, принцип я пока что не понял)

Нужно что-то такое:

во втором варианте я использую следующий способ:

в циклах for меняю endX и endY:

int aX = endX - startX;
int aY = endY - startY;
int aZ = endZ - startZ;

и после в цикле for меняю множитель (шаг):

int aX1 = aX * multiplier;
int aY1 = aY * multiplier;
int aZ1 = aZ * multiplier;

Шаг приходится уменьшать, чтобы избежать ошибок отрисовки. Чтобы отказаться от шага - нужно ориентироваться по сетке. Но тогда требуется для этого некоторая формула, которую я не знаю.

При этом сетка проходит по 0, по 1, по 2 и т.д., а куб находится между 0 и 1. В идеале сетка должна проходить по 0.5, по 1.5, 2.5 и т.д. - это уже задел на будущее

31.12: Попробовал я демонстрационный пример. Попробовал пример - не изучил, очень постараюсь с ним разобраться, т.к. хотелось бы менять размер сетки, для оптимизации по типу "Voxel Octrees". С примером работает в 20 раз быстрее, чем просто с шагом. При разрешении 640х480 всё хорошо, потому что соотношение сторон почти одинаковое, а вот при FHD и соотношении 16:9 уже начинаются проблемы:

Жёлтым это призма (угол обзора), красным сам куб. Пытался домножать aX (чуть выше) на какой-то коэффициент, однако не преуспел. Меняется пропорция по высоте или ширине (цифры, где я указал количество пикселей), однако левый-нижний угол и диагональ правого-верхнего угла продолжают различаться, что плохо. Пока что я не понимаю, что и на что требуется умножить?

c++
  • 2 个回答
  • 208 Views
Martin Hope
Боков Глеб
Asked: 2023-11-23 09:38:33 +0000 UTC

在本地开发和生产模式下使用版本控制系统跟踪 SSL 密钥和证书是否安全?

  • 9

如您所知,带有环境变量的文件(通常具有带或不带文件名的扩展名.env)通常不会被版本控制系统跟踪,以防止数据库密码等数据泄露。SLL 密钥和证书文件怎么样?我请你分别考虑本地开发、分期和制作的情况。

关于这个话题的思考过程

本土化发展模式

如果在本地开发模式下您使用自行颁发的(例如,使用mkcert)SSL 密钥和证书,那么通常我认为没有理由将它们排除在版本控制系统的跟踪之外。它似乎不包含任何敏感数据。

强制每个团队成员自己颁发证书的唯一可能原因是 mkcert 中可能缺少强制浏览器信任已颁发证书的命令。如果确实没有这样的命令,那么每个参与者都必须自己运行该命令mkcert,这不仅会颁发密钥和证书,而且浏览器也会信任它们。在 Windows 上没有 mkcert 的情况下执行此操作并不容易(在我提出问题时我无法做到这一点)。

根据评论更新

正如@andreymal 评论的那样,

如果您将自行颁发的证书添加到受信任的浏览器中,那么泄露其私钥将允许攻击者发起中间人攻击,因此非常危险

我希望这不会成为在本地开发模式下仅使用 HTTP 协议(​​而不是 HTTPS)的理由。

生产

我不确定,但我认为生产模式的 SSL 密钥和证书是不应泄露的秘密信息。有一定的可能性,它们也可以使用浏览器开发者模式作为 CSS 或 JS 文件进行一般查看,但这又是一个假设。

与本地开发模式下每个团队成员都可以拥有自己的自行颁发的 SSL 密钥和证书不同,在生产模式下,每个人都会有一个密钥和一个证书(很可能由授权组织以可报销的方式颁发)。如果是这样,它们将不得不被排除在版本控制之外,并以其他方式在团队成员之间转移。

根据评论更新

有人提出这样的问题:如果理论上一两个生产服务器管理员知道就足够了,为什么团队成员应该了解生产 SSL?我的答案是:根据项目组装和部署的自动化的组织方式,有时在源代码文件中拥有 SLL 密钥和证书会很方便。

首先值得警惕的是,只有生产服务器的管理员才应该知道 SSL 密钥。我并不是说这是错误的,但在这种情况下,当只有一两个团队成员拥有 SSL 密钥和证书时,可能会出现问题。例如,管理员没有上班,但需要发布应用程序修补程序。或者应用程序运行所需的文件分散在团队成员中而不是组织在一起。

再说一次,我并不是说每个人都应该这样做,但我将项目收集在一个文件夹中,该文件夹中放置了应用程序在服务器上工作所需的所有内容,特别是 ssl 密钥、证书和环境变量文件:

在此输入图像描述

因此,构建项目后,剩下的就是以一种或另一种方式将文件发送到 VPS 并docker compose build在 VPS 上重新启动它。

我知道有各种各样的高级部署方法,特别是 GitHub 上的 CI/CD 或各种 AWS 工具。例如,您可以使用 AWS 组织环境变量的注入,而无需使用 .env 文件 - SSL 可能有类似的东西。但所有这些都将开发商与特定的供应商联系在一起。有时这是合理的,但当最初只有一个使用裸 Ubuntu 的 VPS 时,仍然必须有某种方法来有效地组织部署。

ssl
  • 2 个回答
  • 147 Views
上一页
下一页

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5